Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Source files
src/
test/
*.ts

# Development files
tsconfig.json
.gitignore
.npmignore
CONTRIBUTING.md

# Build artifacts
*.tsbuildinfo
.tap/

# Test coverage
coverage/
.nyc_output/

# Git
.git/
.github/

# IDE
.vscode/
.idea/
*.swp
*.swo
*~

# Dependencies
node_modules/
110 changes: 9 additions & 101 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,6 @@ Write JS code that you can run on servers, browsers or other clients.

<!-- toc -->

- [Introduction](#introduction)
- [Socket example](#socket-example)
* [Module](#module)
* [Server](#server)
* [Client](#client)
- [Repl](#repl)
- [Async/Await](#asyncawait)
- [TypeScript](#typescript)
- [Tests](#tests)
- [Formatting](#formatting)
- [Changelog](#changelog)
- [Dependencies](#dependencies)
- [License](#license)
- [Roadmap](#roadmap)

<!-- tocstop -->

## Introduction

There has been interest in improving APIs by allowing aggregations in a
Expand All @@ -47,21 +30,21 @@ using more advanced (de)serialization libraries.
SendScript produces an intermediate JSON representation of the program. Let's see what that looks like.

```js
import stringify from 'sendscript/stringify.mjs'
import module from 'sendscript/module.mjs'
import stringify from 'sendscript/stringify.js'
import module from 'sendscript/module.js'

const { add } = module(['add'])

console.log(stringify(add(1,2)))
```
```json
["call",["ref","add"],[1,2]]
["call",["ref","add"],[["leaf","1"],["leaf","2"]]]
```

We can then parse that JSON and it will evaluate down to a value.

```js
import Parse from 'sendscript/parse.mjs'
import Parse from 'sendscript/parse.js'

const module = {
add(a, b) {
Expand Down Expand Up @@ -122,7 +105,7 @@ Here a socket.io server that runs SendScript programs.
// ./example/server.socket.io.mjs

import { Server } from 'socket.io'
import Parse from 'sendscript/parse.mjs'
import Parse from 'sendscript/parse.js'
import * as math from './math.mjs'

const parse = Parse(math)
Expand Down Expand Up @@ -152,8 +135,8 @@ Now for a client that sends a program to the server.
// ./example/client.socket.io.mjs

import socketClient from 'socket.io-client'
import stringify from 'sendscript/stringify.mjs'
import module from 'sendscript/module.mjs'
import stringify from 'sendscript/stringify.js'
import module from 'sendscript/module.js'
import * as math from './math.mjs'
import assert from 'node:assert'

Expand Down Expand Up @@ -253,7 +236,7 @@ We want to use this module on the client. We create a client version of that mod
cat ./example/typescript/math.client.ts
```
```ts
import module from 'sendscript/module.mjs'
import module from 'sendscript/module.js'
import type * as mathTypes from './math.ts'

const math = module([
Expand All @@ -270,7 +253,7 @@ We now use the client version of this module.
cat ./example/typescript/client.ts
```
```ts
import stringify from 'sendscript/stringify.mjs'
import stringify from 'sendscript/stringify.js'

async function send<T>(program: T): Promise<T>{
return (await fetch('/api', {
Expand All @@ -295,78 +278,3 @@ npm install --no-save \

npx typedoc --plugin typedoc-plugin-markdown --out ./example/typescript/docs ./example/typescript/math.ts
```

You can see the docs [here](./example/typescript/docs/globals.md)

> [!NOTE]
> Although type coercion on the client side can improve the development
> experience, it does not represent the actual type.
> Values are subject to serialization and deserialization.

## Tests

Tests with 100% code coverage.

```bash
npm t -- -R silent
npm t -- report text-summary
```
```

> sendscript@1.0.6 test
> tap -R silent


> sendscript@1.0.6 test
> tap report text-summary


=============================== Coverage summary ===============================
Statements : 100% ( 245/245 )
Branches : 100% ( 74/74 )
Functions : 100% ( 18/18 )
Lines : 100% ( 245/245 )
================================================================================
```

## Formatting

Standard because no config.

```bash
npx standard
```

## Changelog

The [changelog][changelog] is generated using the useful
[auto-changelog][auto-changelog] project.

```bash
npx auto-changelog -p
```

## Dependencies

Check if packages are up to date on release.

```bash
npm outdated && echo 'No outdated packages found'
```
```
No outdated packages found
```

## License

See the [LICENSE.txt][license] file for details.

## Roadmap

- [ ] Support for simple lambdas to compose functions more easily.

[license]:./LICENSE.txt
[socket.io]:https://socket.io/
[changelog]:./CHANGELOG.md
[auto-changelog]:https://www.npmjs.com/package/auto-changelog
[typedoc]:https://github.com/TypeStrong/typedoc
66 changes: 60 additions & 6 deletions README.mz
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ using more advanced (de)serialization libraries.
SendScript produces an intermediate JSON representation of the program. Let's see what that looks like.

```js|json node --input-type=module | tee /tmp/sendscript.json
import stringify from 'sendscript/stringify.mjs'
import module from 'sendscript/module.mjs'
import stringify from 'sendscript/stringify.js'
import module from 'sendscript/module.js'

const { add } = module(['add'])

Expand All @@ -41,7 +41,7 @@ console.log(stringify(add(1,2)))
We can then parse that JSON and it will evaluate down to a value.

```js|json node --input-type=module
import Parse from 'sendscript/parse.mjs'
import Parse from 'sendscript/parse.js'

const module = {
add(a, b) {
Expand Down Expand Up @@ -99,7 +99,7 @@ Here a socket.io server that runs SendScript programs.
// ./example/server.socket.io.mjs

import { Server } from 'socket.io'
import Parse from 'sendscript/parse.mjs'
import Parse from 'sendscript/parse.js'
import * as math from './math.mjs'

const parse = Parse(math)
Expand Down Expand Up @@ -129,8 +129,8 @@ Now for a client that sends a program to the server.
// ./example/client.socket.io.mjs

import socketClient from 'socket.io-client'
import stringify from 'sendscript/stringify.mjs'
import module from 'sendscript/module.mjs'
import stringify from 'sendscript/stringify.js'
import module from 'sendscript/module.js'
import * as math from './math.mjs'
import assert from 'node:assert'

Expand Down Expand Up @@ -246,6 +246,60 @@ You can see the docs [here](./example/typescript/docs/globals.md)
> experience, it does not represent the actual type.
> Values are subject to serialization and deserialization.

## Leaf Serializer

By default, SendScript uses JSON for serialization, which limits support to primitives and plain objects/arrays. To support richer JavaScript types like `Date`, `RegExp`, `BigInt`, `Map`, `Set`, and `undefined`, you can provide custom serialization functions.

The `stringify` function accepts an optional `leafSerializer` parameter, and `parse` accepts an optional `leafDeserializer` parameter. These functions control how non-SendScript values (leaves) are encoded and decoded.

### Example with superjson

Here's how to use [superjson](https://github.com/blitz-js/superjson) to support extended types:

```js
import SuperJSON from 'superjson'
import stringify from 'sendscript/stringify.mjs'
import Parse from 'sendscript/parse.mjs'
import module from 'sendscript/module.mjs'

const leafSerializer = (value) => {
if (value === undefined) return JSON.stringify({ __undefined__: true })
return JSON.stringify(SuperJSON.serialize(value))
}

const leafDeserializer = (text) => {
const parsed = JSON.parse(text)
if (parsed && parsed.__undefined__ === true) return undefined
return SuperJSON.deserialize(parsed)
}

const { processData } = module(['processData'])

// Program with Date, RegExp, and other types
const program = {
createdAt: new Date('2020-01-01T00:00:00.000Z'),
pattern: /foo/gi,
count: BigInt('9007199254740992'),
items: new Set([1, 2, 3]),
mapping: new Map([['a', 1], ['b', 2]])
}

// Serialize with custom leaf serializer
const json = stringify(processData(program), leafSerializer)

// Parse with custom leaf deserializer
const parse = Parse({
processData: (data) => ({
success: true,
received: data
})
})

const result = parse(json, leafDeserializer)
```

The leaf wrapper format is `['leaf', serializedPayload]`, making it unambiguous and safe from colliding with SendScript operators.

## Tests

Tests with 100% code coverage.
Expand Down
15 changes: 0 additions & 15 deletions cli.mjs

This file was deleted.

11 changes: 0 additions & 11 deletions curry.mjs

This file was deleted.

35 changes: 0 additions & 35 deletions curry.test.mjs

This file was deleted.

5 changes: 0 additions & 5 deletions debug.mjs

This file was deleted.

3 changes: 3 additions & 0 deletions dist/cli.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env node
export {};
//# sourceMappingURL=cli.d.ts.map
1 change: 1 addition & 0 deletions dist/cli.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions dist/cli.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions dist/cli.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions dist/curry.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export default function curry<T extends (...args: any[]) => any>(func: T): (...args: any[]) => any;
//# sourceMappingURL=curry.d.ts.map
Loading