streamotter 0.1.0-rc.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Orca Solutions
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,106 @@
1
+ <p align="center"><img src="https://raw.githubusercontent.com/jfricano/StreamOtter/main/docs/assets/streamotter-logo.png" alt="StreamOtter" width="420"></p>
2
+
3
+ # StreamOtter
4
+
5
+ Live state from Kafka in the browser, in a form you can trust. Browsers subscribe to **state channels**, not raw topics. Each view starts from an authoritative snapshot, then receives full-state updates in revision order, and is always either verifiably `live` or visibly `stale`, never silently wrong after a disconnect, a restart, or a slow client. Your own handlers decide who may see what.
6
+
7
+ This package is StreamOtter in one install: the `streamotter` command (scaffold, validate, generate TypeScript types, develop with the local workbench, and run the production gateway), the Node.js gateway, and the browser SDK.
8
+
9
+ > **Release candidate** of StreamOtter `0.1.0`; the API may still change before `0.1.0`. Package versions follow SemVer independently of the V1 protocol and `configVersion: 1`.
10
+
11
+ ```bash
12
+ npm install streamotter
13
+ ```
14
+
15
+ Node.js 24 or later for the gateway and CLI; current evergreen browsers for the SDK. ESM only, with TypeScript declarations included.
16
+
17
+ ## Try it
18
+
19
+ In a new folder; no Kafka needed, because the scaffold uses a built-in fixture source:
20
+
21
+ ```bash
22
+ npm init -y
23
+ npm install streamotter
24
+ npx streamotter init .
25
+ npx streamotter dev --config streamotter.json --handlers server/handlers.mjs
26
+ ```
27
+
28
+ Open the workbench URL that `dev` prints and paste its one-time token. Then preview the `jobProgress` channel as the `developer` principal, and advance the `jobs` fixture to watch revisions arrive. [Getting started](https://github.com/jfricano/StreamOtter/blob/main/docs/guides/getting-started.md) continues from there to a real web page.
29
+
30
+ ## What to import
31
+
32
+ | Import | Where | What |
33
+ | --- | --- | --- |
34
+ | `streamotter/client` | Browser | The SDK: `createClient`, subscriptions, `live`/`stale` states, and errors. Bundles only the SDK and the Socket.IO client. |
35
+ | `streamotter/gateway` | Node.js | `createGateway`, `defineProject`, and the types for your handlers (`HandlerRegistry`, `Principal`, …) |
36
+ | `streamotter/gateway/management` | Node.js | The development management API that `streamotter dev` uses |
37
+ | `streamotter/contracts` | Anywhere | Shared types, protocol constants, and configuration validation |
38
+ | `streamotter/cli` | Node.js | The CLI's programmatic API (`runCli`, `generateFiles`) |
39
+
40
+ There is no bare `import "streamotter"`. Browser code and server code are separate subpaths, so a browser bundle never pulls in the gateway.
41
+
42
+ ```ts
43
+ // Browser
44
+ import { createClient } from "streamotter/client";
45
+ import { channelVersions, type AppChannels } from "./generated/streamotter.generated.js";
46
+
47
+ const client = createClient<AppChannels>({ getToken: () => session.getAccessToken() });
48
+ const job = client.subscribe("jobProgress", { channelVersion: channelVersions.jobProgress, params: { jobId: "job_1" } });
49
+ job.on("data", ({ data }) => render(data)); // full state: replace, don't merge
50
+ job.on("state", ({ state }) => showDeliveryState(state)); // anything but "live" may be out of date
51
+ ```
52
+
53
+ ```ts
54
+ // Server: your trusted handlers, loaded by `streamotter dev` or `streamotter start`
55
+ import type { HandlerRegistry } from "streamotter/gateway";
56
+ import type { AppChannels } from "./generated/streamotter.generated.js";
57
+
58
+ export const handlers: HandlerRegistry<AppChannels> = {
59
+ authenticate: ({ token }) => verifySession(token), // your session check → Principal | null
60
+ channels: {
61
+ jobProgress: {
62
+ authorize: ({ principal, params }) => canSeeJob(principal, params.jobId),
63
+ snapshot: ({ params }) => readJob(params.jobId), // → { revision, data } from your store
64
+ map: ({ record }) => jobStatesFrom(record) // Kafka record → the states it updates
65
+ }
66
+ }
67
+ };
68
+ ```
69
+
70
+ `streamotter init` and `streamotter generate` write code that imports from `streamotter/…` when your `package.json` lists `streamotter` (and not `@streamotter/client`).
71
+
72
+ ## `streamotter` or the individual packages?
73
+
74
+ | Your project | Install |
75
+ | --- | --- |
76
+ | Trying StreamOtter, or one project with both the web app and the gateway | `streamotter` |
77
+ | A frontend that lives apart from the gateway | [`@streamotter/client`](https://www.npmjs.com/package/@streamotter/client) alone: small, with no Node.js requirement and no server libraries |
78
+ | A gateway service | [`@streamotter/cli`](https://www.npmjs.com/package/@streamotter/cli), plus [`@streamotter/gateway`](https://www.npmjs.com/package/@streamotter/gateway) for handler types or programmatic use |
79
+
80
+ Pick one style per project: import from `streamotter/…` if you installed `streamotter`, and from `@streamotter/…` if you installed those packages. With pnpm, packages you didn't install directly aren't importable.
81
+
82
+ ## Documentation
83
+
84
+ - [Getting started](https://github.com/jfricano/StreamOtter/blob/main/docs/guides/getting-started.md): from `npm install` to a live page in about ten minutes
85
+ - [Add live state to an existing app](https://github.com/jfricano/StreamOtter/blob/main/docs/guides/existing-app.md): your sessions, your database, Kafka events, access changes, and React
86
+ - [Connect to Kafka](https://github.com/jfricano/StreamOtter/blob/main/docs/guides/kafka.md): topic shape, TLS and SASL, bad records, crashes, and diagnostics
87
+ - [Run in production](https://github.com/jfricano/StreamOtter/blob/main/docs/DEPLOYMENT.md): `streamotter start`, supervision, and the reverse-proxy recipe
88
+ - [Troubleshooting](https://github.com/jfricano/StreamOtter/blob/main/docs/guides/troubleshooting.md)
89
+ - Package guides: [client](https://www.npmjs.com/package/@streamotter/client) (states, errors, cleanup, a React hook), [gateway](https://www.npmjs.com/package/@streamotter/gateway) (handlers, revisions, revocation), and [CLI](https://www.npmjs.com/package/@streamotter/cli) (commands, workbench, exit codes)
90
+ - [Implementation status](https://github.com/jfricano/StreamOtter/blob/main/docs/IMPLEMENTATION_STATUS.md): what is verified, and the V1 limits (one gateway per project, no durable replay)
91
+ - [Repository](https://github.com/jfricano/StreamOtter) · [Issues](https://github.com/jfricano/StreamOtter/issues) · [Security policy](https://github.com/jfricano/StreamOtter/blob/main/SECURITY.md)
92
+
93
+ ## StreamOtter packages
94
+
95
+ | Package | |
96
+ | --- | --- |
97
+ | [`streamotter`](https://www.npmjs.com/package/streamotter) | **This package.** Everything below in one install, with the `streamotter` command |
98
+ | [`@streamotter/cli`](https://www.npmjs.com/package/@streamotter/cli) | Scaffold, validate, generate types, develop with the workbench, and run the production gateway |
99
+ | [`@streamotter/client`](https://www.npmjs.com/package/@streamotter/client) | The browser SDK: subscribe, render `live` and `stale`, and clean up |
100
+ | [`@streamotter/gateway`](https://www.npmjs.com/package/@streamotter/gateway) | Handler types, and running the gateway from your own Node.js code |
101
+ | [`@streamotter/contracts`](https://www.npmjs.com/package/@streamotter/contracts) | Shared types and configuration validation, for tooling authors |
102
+ | [`@streamotter/workbench`](https://www.npmjs.com/package/@streamotter/workbench) | The local workbench's assets, installed by the CLI |
103
+
104
+ All six are released together with the same version ([changelog](https://github.com/jfricano/StreamOtter/blob/main/CHANGELOG.md)).
105
+
106
+ MIT License © 2026 Orca Solutions
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { runProcess } from "@streamotter/cli";
3
+
4
+ await runProcess();
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ /** The CLI's programmatic API, re-exported from @streamotter/cli. */
2
+ export * from "@streamotter/cli";
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,cAAc,kBAAkB,CAAC"}
package/dist/cli.js ADDED
@@ -0,0 +1,3 @@
1
+ /** The CLI's programmatic API, re-exported from @streamotter/cli. */
2
+ export * from "@streamotter/cli";
3
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** The browser SDK, re-exported from @streamotter/client. */
2
+ export * from "@streamotter/client";
3
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,cAAc,qBAAqB,CAAC"}
package/dist/client.js ADDED
@@ -0,0 +1,3 @@
1
+ /** The browser SDK, re-exported from @streamotter/client. */
2
+ export * from "@streamotter/client";
3
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,cAAc,qBAAqB,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** Shared types and validation, re-exported from @streamotter/contracts. */
2
+ export * from "@streamotter/contracts";
3
+ //# sourceMappingURL=contracts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,cAAc,wBAAwB,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** Shared types and validation, re-exported from @streamotter/contracts. */
2
+ export * from "@streamotter/contracts";
3
+ //# sourceMappingURL=contracts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contracts.js","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,cAAc,wBAAwB,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** The Node.js gateway, re-exported from @streamotter/gateway. */
2
+ export * from "@streamotter/gateway";
3
+ //# sourceMappingURL=gateway.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway.d.ts","sourceRoot":"","sources":["../src/gateway.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,cAAc,sBAAsB,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** The Node.js gateway, re-exported from @streamotter/gateway. */
2
+ export * from "@streamotter/gateway";
3
+ //# sourceMappingURL=gateway.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway.js","sourceRoot":"","sources":["../src/gateway.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,cAAc,sBAAsB,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** The development management API, re-exported from @streamotter/gateway/management. */
2
+ export * from "@streamotter/gateway/management";
3
+ //# sourceMappingURL=management.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"management.d.ts","sourceRoot":"","sources":["../src/management.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,cAAc,iCAAiC,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** The development management API, re-exported from @streamotter/gateway/management. */
2
+ export * from "@streamotter/gateway/management";
3
+ //# sourceMappingURL=management.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"management.js","sourceRoot":"","sources":["../src/management.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,cAAc,iCAAiC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,76 @@
1
+ {
2
+ "name": "streamotter",
3
+ "version": "0.1.0-rc.3",
4
+ "description": "StreamOtter in one install: the CLI and local workbench, the Node.js gateway, and the browser SDK, for live Kafka state in the browser that is either verifiably live or visibly stale.",
5
+ "keywords": [
6
+ "streamotter",
7
+ "kafka",
8
+ "socket.io",
9
+ "websocket",
10
+ "realtime",
11
+ "live-data",
12
+ "state-sync",
13
+ "gateway",
14
+ "browser",
15
+ "typescript"
16
+ ],
17
+ "homepage": "https://github.com/jfricano/StreamOtter#readme",
18
+ "bugs": {
19
+ "url": "https://github.com/jfricano/StreamOtter/issues"
20
+ },
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "git+https://github.com/jfricano/StreamOtter.git",
24
+ "directory": "packages/streamotter"
25
+ },
26
+ "license": "MIT",
27
+ "author": "Orca Solutions",
28
+ "type": "module",
29
+ "sideEffects": false,
30
+ "bin": {
31
+ "streamotter": "./bin/streamotter.js"
32
+ },
33
+ "exports": {
34
+ "./client": {
35
+ "types": "./dist/client.d.ts",
36
+ "default": "./dist/client.js"
37
+ },
38
+ "./gateway": {
39
+ "types": "./dist/gateway.d.ts",
40
+ "default": "./dist/gateway.js"
41
+ },
42
+ "./gateway/management": {
43
+ "types": "./dist/management.d.ts",
44
+ "default": "./dist/management.js"
45
+ },
46
+ "./contracts": {
47
+ "types": "./dist/contracts.d.ts",
48
+ "default": "./dist/contracts.js"
49
+ },
50
+ "./cli": {
51
+ "types": "./dist/cli.d.ts",
52
+ "default": "./dist/cli.js"
53
+ },
54
+ "./package.json": "./package.json"
55
+ },
56
+ "files": [
57
+ "bin",
58
+ "dist",
59
+ "src"
60
+ ],
61
+ "engines": {
62
+ "node": ">=24"
63
+ },
64
+ "publishConfig": {
65
+ "access": "public"
66
+ },
67
+ "dependencies": {
68
+ "@streamotter/cli": "0.1.0-rc.3",
69
+ "@streamotter/client": "0.1.0-rc.3",
70
+ "@streamotter/contracts": "0.1.0-rc.3",
71
+ "@streamotter/gateway": "0.1.0-rc.3"
72
+ },
73
+ "devDependencies": {
74
+ "@types/node": "24.13.6"
75
+ }
76
+ }
package/src/cli.ts ADDED
@@ -0,0 +1,2 @@
1
+ /** The CLI's programmatic API, re-exported from @streamotter/cli. */
2
+ export * from "@streamotter/cli";
package/src/client.ts ADDED
@@ -0,0 +1,2 @@
1
+ /** The browser SDK, re-exported from @streamotter/client. */
2
+ export * from "@streamotter/client";
@@ -0,0 +1,2 @@
1
+ /** Shared types and validation, re-exported from @streamotter/contracts. */
2
+ export * from "@streamotter/contracts";
package/src/gateway.ts ADDED
@@ -0,0 +1,2 @@
1
+ /** The Node.js gateway, re-exported from @streamotter/gateway. */
2
+ export * from "@streamotter/gateway";
@@ -0,0 +1,2 @@
1
+ /** The development management API, re-exported from @streamotter/gateway/management. */
2
+ export * from "@streamotter/gateway/management";