Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Saber Functions #183

Open
egoist opened this issue May 14, 2019 · 8 comments · May be fixed by #381
Open

Saber Functions #183

egoist opened this issue May 14, 2019 · 8 comments · May be fixed by #381
Assignees
Labels
💵 Funded on Issuehunt This issue has been funded on Issuehunt 💬RFC type: feature wip Work In Progress

Comments

@egoist
Copy link
Collaborator

egoist commented May 14, 2019

Issuehunt badges

RFC: Saber Functions

functions folder

Functions are used to fetch data that you can inject to pages at build time, let's say you have a posts.js inside functions folder:

exports.handler = async ({ type }) => {
  const posts = await getAllPostsFromApi()
  return posts.filter(post => post.type === type)
}

Since we need to get the return value before running webpack, you can only write JavaScript with features supported by your system's Node version.

Then a function called posts will be available and you can use it like this in a page:

<script>
export const config = {
  injectProps: {
    drafts: {
      function: 'posts',
      options: {
        type: 'draft'
      }
    }
  }
}

export default {
  props: ['drafts']
}
</script>

By using injectProps here Saber will call the function at build time and inline result in your JavaScript bundle.

Pagination

We can create pagination based on injected props:

<script>
export const config = {
  paginate: {
    prop: 'drafts',
    perPage: 30
  },

  injectProps: {
    drafts: {
      function: 'posts',
      options: {
        type: 'draft'
      }
    }
  }
}

export default {
  props: ['drafts']
}
</script>

Exporting function

A function can be exported as a page just like a normal page, only thing you need to do is setting config.export option to true:

// functions/atom.xml.js
const getPosts = require('../get-posts')

exports.handler = async () => {
  const posts = await getPosts({ type: 'public' })
  const xml = generateXMLFeed(posts)
  return xml
}

exports.config = {
  export: true
}

When export is true, Saber automatically infers the actual link from its filename, in this case it would be /atom.xml. You can also set it to a string to use whatever permalink you want, e.g. /subscribe/rss.xml.

When export is true, the function's argument would be undefined unless you use dynamic parameter in its filename, for example functions/pages/[slug].json.js:

exports.handler = ({ slug }) => {
  return getPageBySlug(slug)
}

exports.config = {
  export: true
}

exports.getStaticPaths = () => {
  return [
    { slug: 'hello-world' },
    { slug: 'another-page' }
  ]
}

Because the path is dynamic you also need getStaticPaths to define a list of paths that need to be rendered at build time.

Now when you visit /pages/hello-world.json, then function argument will be { slug: 'hello-world' }

Adding a function from plugins

saber.functions.add(FunctionObject)

IssueHunt Summary

Backers (Total: $150.00)

Become a backer now!

Or submit a pull request to get the deposits!

Tips


IssueHunt has been backed by the following sponsors. Become a sponsor

@egoist egoist added the 💬RFC label May 14, 2019
@egoist egoist changed the title Static Routes [RFC] Static Routes May 14, 2019
@krmax44
Copy link
Contributor

krmax44 commented May 14, 2019

Maybe "Functional Routes" or "Manual Routes"?

@egoist
Copy link
Collaborator Author

egoist commented May 19, 2019

#72 won't be needed if we have this feature instead.

@egoist egoist changed the title [RFC] Static Routes [RFC] Saber Functions Jun 25, 2019
@egoist egoist changed the title [RFC] Saber Functions Saber Functions Jun 25, 2019
@issuehunt-oss issuehunt-oss bot added the 💵 Funded on Issuehunt This issue has been funded on Issuehunt label Jun 25, 2019
@issuehunt-oss
Copy link

issuehunt-oss bot commented Jun 25, 2019

@issuehunt has funded $150.00 to this issue.


@egoist egoist self-assigned this Jun 25, 2019
@galvez
Copy link

galvez commented Jun 25, 2019

In NuxtPress (currently in development), I did a generic abstraction of this.

Every source is identified by a full path. For every source, the engine automatically does a GET request to /api/source/{uri}.

If you don't provide your own API handlers, it will perform static fetch() to the distribution.

A source is a JSON with { body, type }. Different types can be used to trigger different rendering components.

So in generate mode, if you have a route something/foobar.md, source type will be md and it will go through the Markdown loader.

A /static/sources/something/foobar.json will also be made available for the static JSON GET.

Then agan, if you do provide your own API handlers, data can come from anywhere you like.

@egoist egoist added the wip Work In Progress label Aug 22, 2019
@egoist egoist linked a pull request Aug 23, 2019 that will close this issue
9 tasks
@krmax44
Copy link
Contributor

krmax44 commented Sep 7, 2019

I also quite like the implementation that Sapper uses: https://sapper.svelte.dev/docs#Server_routes

@egoist
Copy link
Collaborator Author

egoist commented Apr 15, 2020

Just updated the proposal ⬆️

@egoist egoist added the 💬RFC label Apr 15, 2020
@krmax44
Copy link
Contributor

krmax44 commented Apr 27, 2021

I'm currently building something similar: rollup-plugin-computed

@TYKUHN2
Copy link

TYKUHN2 commented Aug 6, 2022

Is this project still being worked on? The website seems parked by adware/viruses. If it is, I can take a look at this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
💵 Funded on Issuehunt This issue has been funded on Issuehunt 💬RFC type: feature wip Work In Progress
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants