11# SendScript
22
3- Write JS code that you can run on servers, browsers or other clients .
3+ RPC and no-build with composable function calls in a single payload .
44
55[ ![ NPM] ( https://img.shields.io/npm/v/sendscript?color=blue\& style=flat-square )] ( https://www.npmjs.com/package/sendscript )
66[ ![ 100% Code Coverage] ( https://img.shields.io/badge/coverage-100%25-brightgreen?style=flat-square )] ( #tests )
@@ -25,17 +25,25 @@ Write JS code that you can run on servers, browsers or other clients.
2525 * [ Server] ( #server )
2626 * [ Client] ( #client )
2727- [ Repl] ( #repl )
28- - [ Functions] ( #functions )
2928- [ Promises] ( #promises )
3029 * [ .then / .catch] ( #then--catch )
3130 * [ await] ( #await )
31+ - [ Promises] ( #promises-1 )
32+ * [ .then / .catch] ( #then--catch-1 )
33+ * [ await] ( #await-1 )
3234- [ TypeScript] ( #typescript )
3335- [ Schema and Nested Modules] ( #schema-and-nested-modules )
3436 * [ Defining a Nested Module] ( #defining-a-nested-module )
3537- [ Validation (using Zod)] ( #validation-using-zod )
3638 * [ Validating structured input] ( #validating-structured-input )
3739- [ Leaf Serializer] ( #leaf-serializer )
3840 * [ Example with superjson] ( #example-with-superjson )
41+ - [ Limitations] ( #limitations )
42+ * [ Chaining APIs] ( #chaining-apis )
43+ * [ Callbacks] ( #callbacks )
44+ * [ Error handling] ( #error-handling )
45+ - [ Tests] ( #tests )
46+ - [ Formatting] ( #formatting )
3947- [ Changelog] ( #changelog )
4048- [ License] ( #license )
4149- [ Issues] ( #issues )
@@ -121,7 +129,7 @@ piqued your interest.
121129
122130### defaultLeafParse
123131
124- [ parse.mjs:49-49] ( https://github.com/bas080/sendscript/blob/5249a85a08b10485f0d64058fd2c8bcaae84edda /parse.mjs#L49-L49 " Source code on GitHub ")
132+ [ parse.mjs:49-49] ( https://github.com/bas080/sendscript/blob/3f1041020e00331ff30ffb5f972738dbaf7a50f3 /parse.mjs#L49-L49 " Source code on GitHub ")
125133
126134Default deserializer for leaf nodes.
127135
@@ -133,7 +141,7 @@ Returns **any** 
133141
134142### Parse
135143
136- [ parse.mjs:68-215] ( https://github.com/bas080/sendscript/blob/5249a85a08b10485f0d64058fd2c8bcaae84edda /parse.mjs#L68-L215 " Source code on GitHub ")
144+ [ parse.mjs:68-215] ( https://github.com/bas080/sendscript/blob/3f1041020e00331ff30ffb5f972738dbaf7a50f3 /parse.mjs#L68-L215 " Source code on GitHub ")
137145
138146#### Parameters
139147
@@ -145,7 +153,7 @@ Returns **[parse](#parse)** 
145153
146154### parse
147155
148- [ parse.mjs:78-214] ( https://github.com/bas080/sendscript/blob/5249a85a08b10485f0d64058fd2c8bcaae84edda /parse.mjs#L78-L214 " Source code on GitHub ")
156+ [ parse.mjs:78-214] ( https://github.com/bas080/sendscript/blob/3f1041020e00331ff30ffb5f972738dbaf7a50f3 /parse.mjs#L78-L214 " Source code on GitHub ")
149157
150158Parses and executes a serialized program.
151159
@@ -157,7 +165,7 @@ Returns **(any | [Promise](https://developer.mozilla.org/docs/Web/JavaScript/Ref
157165
158166### References
159167
160- [ references.mjs:109-127] ( https://github.com/bas080/sendscript/blob/5249a85a08b10485f0d64058fd2c8bcaae84edda /references.mjs#L109-L127 " Source code on GitHub ")
168+ [ references.mjs:109-127] ( https://github.com/bas080/sendscript/blob/3f1041020e00331ff30ffb5f972738dbaf7a50f3 /references.mjs#L109-L127 " Source code on GitHub ")
161169
162170Builds a nested API structure from a schema definition.
163171
@@ -174,15 +182,15 @@ Returns **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/G
174182
175183### SchemaNode
176184
177- [ schema.mjs:1-19] ( https://github.com/bas080/sendscript/blob/5249a85a08b10485f0d64058fd2c8bcaae84edda /schema.mjs#L1-L6 " Source code on GitHub ")
185+ [ schema.mjs:1-19] ( https://github.com/bas080/sendscript/blob/3f1041020e00331ff30ffb5f972738dbaf7a50f3 /schema.mjs#L1-L6 " Source code on GitHub ")
178186
179187A single schema node.
180188
181189Type: ([ string] ( https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String ) | \[ [ string] ( https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String ) , [ Schema] ( #schema )] )
182190
183191### Schema
184192
185- [ schema.mjs:1-19] ( https://github.com/bas080/sendscript/blob/5249a85a08b10485f0d64058fd2c8bcaae84edda /schema.mjs#L8-L18 " Source code on GitHub ")
193+ [ schema.mjs:1-19] ( https://github.com/bas080/sendscript/blob/3f1041020e00331ff30ffb5f972738dbaf7a50f3 /schema.mjs#L8-L18 " Source code on GitHub ")
186194
187195A schema defines the structure of the runtime API tree.
188196
@@ -195,7 +203,7 @@ Type: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global
195203
196204### defaultLeafStringify
197205
198- [ stringify.mjs:37-47] ( https://github.com/bas080/sendscript/blob/5249a85a08b10485f0d64058fd2c8bcaae84edda /stringify.mjs#L37-L47 " Source code on GitHub ")
206+ [ stringify.mjs:37-47] ( https://github.com/bas080/sendscript/blob/3f1041020e00331ff30ffb5f972738dbaf7a50f3 /stringify.mjs#L37-L47 " Source code on GitHub ")
199207
200208Default strict serializer for leaf values.
201209
@@ -209,7 +217,7 @@ Returns **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/G
209217
210218### Stringify
211219
212- [ stringify.mjs:56-157] ( https://github.com/bas080/sendscript/blob/5249a85a08b10485f0d64058fd2c8bcaae84edda /stringify.mjs#L56-L157 " Source code on GitHub ")
220+ [ stringify.mjs:56-157] ( https://github.com/bas080/sendscript/blob/3f1041020e00331ff30ffb5f972738dbaf7a50f3 /stringify.mjs#L56-L157 " Source code on GitHub ")
213221
214222Creates a stringify function for SendScript AST structures.
215223
@@ -221,7 +229,7 @@ Returns **[stringify](#stringify)** 
221229
222230### stringify
223231
224- [ stringify.mjs:64-156] ( https://github.com/bas080/sendscript/blob/5249a85a08b10485f0d64058fd2c8bcaae84edda /stringify.mjs#L64-L156 " Source code on GitHub ")
232+ [ stringify.mjs:64-156] ( https://github.com/bas080/sendscript/blob/3f1041020e00331ff30ffb5f972738dbaf7a50f3 /stringify.mjs#L64-L156 " Source code on GitHub ")
225233
226234Serializes a program into a JSON string representation.
227235
@@ -336,13 +344,27 @@ pkill sendscript
336344
337345## Repl
338346
339- Sendscript ships with a barebones (no-dependencies) node-repl script. One can
347+ Sendscript ships with a bare-bones (no-dependencies) node-repl script. One can
340348run it by simply typing ` sendscript ` in their console.
341349
342- > Use the ` DEBUG='*' ` to enable all logs or ` DEBUG='sendscript:*' ` for
343- > printingonly sendscript logs.
350+ > Use the ` DEBUG='*' ` to enable all logs or ` DEBUG='sendscript:*' ` for printing
351+ > only sendscript logs.
344352
345- ## Functions
353+ ## Promises
354+
355+ ### .then / .catch
356+
357+ Supported since vs ` v2.3 ` .
358+
359+ ``` js
360+ const getOrCreatePost = send (createPost (title).catch (createPost (title)))
361+ ```
362+
363+ You will likely need to define better helpers that makes it safer to handle
364+ rejections and work with promises. It is however sensible to have this basic
365+ behavior for the sendscript DSL and parser.
366+
367+ ### await
346368
347369SendScript as of ` v2.4 ` supports functions to do basic templating. It does not
348370support async functions and will throw an error when you define one.
@@ -584,14 +606,101 @@ const env = {
584606}
585607
586608// Parse with custom leaf deserializer
587- const parse = Parse (schema, env, leadDeserializer )
609+ const parse = Parse (schema, env, leafDeserializer )
588610
589611const result = parse (json)
590612```
591613
592614The leaf wrapper format is ` ['leaf', serializedPayload] ` , making it unambiguous
593615and safe from colliding with SendScript operators.
594616
617+ ## Limitations
618+
619+ The stubs the ` references ` function returns are limited in the way they can be
620+ used. This has to do with the fact that they are to be serialized.
621+
622+ ### Chaining APIs
623+
624+ Currently you cannot do chaining APIs. ` lib().doThis().doThat() ` . It likely is
625+ possible to implement but will require more extensive schemas and obviously more
626+ code to create the AST.
627+
628+ ### Callbacks
629+
630+ Although it is possible to mix client and server functions, it works very
631+ different to ordinary functions. Client functions can be used but should be seen
632+ as a templating tool to make sendscript programs; just like one would use
633+ JavaScript with react templates. ` items.map(deleteItem) ` would return an array
634+ of sendscript function calls which can be given to sendscript's parse.
635+
636+ Client functions cannot be called by sendscript functions (as of yet) since we
637+ cannot serialize client functions. No work has been done to have the server send
638+ back intermediate values to perform client function calls or by performing
639+ smaller sendscript program payloads that are passed to the client. Very
640+ interesting stuff to look into. You can achieve this now but it looks less clean
641+ because you have to do ` send ` calls which is a bit manual.
642+
643+ ``` js
644+ await send (updateUser (id, merge (await send (getUser (id)), { ... newValues })))
645+ ```
646+
647+ It might be interesting to allow configuration to create references that will
648+ trigger a send whenever await is called. That would remove the ability to create
649+ a single payload whenever using await. You can then write the above in the
650+ following manner.
651+
652+ ``` js
653+ await updateUser (id, merge (await getUser (id), { ... newValues }))
654+ ```
655+
656+ Possible footgun is that updateUser is only performed when awaited (.then is
657+ called). This lazy behavior can trip users. This footgun could be resolved by
658+ checking if any outstanding work exists at the end of a step or the beginning of
659+ a new step.
660+
661+ ### Error handling
662+
663+ Sendscript does not have builtin tools to handle errors. You can write your own
664+ utilities for that or use things like \[ Ramda's tryCatch] \[ tryCatch] . This will
665+ likely never be supported as JS try catch does not have a return value. It might
666+ make sense to wrap everything that can throw in promises which is easy to do
667+ with async functions.
668+
669+ ## Tests
670+
671+ Tests with 100% code coverage.
672+
673+ ``` bash
674+ npm t -- -R silent
675+ npm t -- report text-summary
676+ ```
677+
678+ ```
679+
680+ > sendscript@2.4.1 test
681+ > tap -R silent
682+
683+
684+ > sendscript@2.4.1 test
685+ > tap report text-summary
686+
687+
688+ =============================== Coverage summary ===============================
689+ Statements : 100% ( 523/523 )
690+ Branches : 100% ( 153/153 )
691+ Functions : 100% ( 25/25 )
692+ Lines : 100% ( 523/523 )
693+ ================================================================================
694+ ```
695+
696+ ## Formatting
697+
698+ Standard because no config.
699+
700+ ``` bash
701+ npx standard
702+ ```
703+
595704## Changelog
596705
597706The [ changelog] [ changelog ] is generated using the useful
0 commit comments