@empyria/restate 0.1.0

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/.oxfmtrc.json ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "$schema": "./node_modules/oxfmt/configuration_schema.json",
3
+ "ignorePatterns": [],
4
+ "useTabs": true,
5
+ "tabWidth": 4,
6
+ "singleQuote": true,
7
+ "trailingComma": "all",
8
+ "semi": false
9
+ }
package/AGENTS.md ADDED
@@ -0,0 +1,64 @@
1
+ # AGENTS.md
2
+
3
+ Restate.dev helpers for **Principia**, a nanoservice framework built primarily on Bun:
4
+ an Admin API client, a dynamic-dispatch service, cron-driven workflow scheduling, and
5
+ schema validation for workflow handlers.
6
+
7
+ Targets Restate server `1.7.x` and `@restatedev/restate-sdk` `1.6.x` — check both when
8
+ touching version pins; the SDK's own version numbering runs well ahead of the server's
9
+ (e.g. `1.16.x` was latest on npm when `1.6.x` was what this repo targets), so "latest"
10
+ is not the right default here.
11
+
12
+ ## Runtime
13
+
14
+ - Requires Bun `>=1.4.0` or Node.js `>=26`, inherited from `@empyria/classification`'s use
15
+ of native `Temporal`. Both `@empyria/classification` and `@empyria/common` are **git
16
+ dependencies** — this package only sees their pushed commits, not local working-tree changes
17
+ in sibling repos.
18
+ - Plain ESM, no TypeScript, no build step. The original `admin.ts`/`admin.types.ts`/`Caller.ts`
19
+ (and the `generateTypes.sh` script that regenerated `admin.types.ts` from a live server's
20
+ `/openapi` spec) have been removed — `lib/Admin.js`/`lib/Caller.js` are the canonical,
21
+ hand-converted, tested equivalents. There is no generated-types workflow left in this repo;
22
+ if the Admin API needs re-syncing, diff `lib/Admin.js`'s assumptions against a live server's
23
+ `<admin-url>/openapi` by hand.
24
+ - Relative imports must include explicit `.js` extensions — Bun tolerates missing ones, Node's
25
+ ESM resolver doesn't.
26
+
27
+ ## No official Admin API client
28
+
29
+ Verified directly against the published `@restatedev/restate-sdk`/`-clients` package
30
+ internals (both the `1.6.x` line this repo targets and the latest available at the time):
31
+ zero Admin API exports. Only the ingress/invocation client and the service-authoring API
32
+ (`restate.service`/`object`/`workflow`) are official. `lib/Admin.js` fetches the Admin API's
33
+ REST endpoints directly — that's not a stopgap, it's the only way to do this today.
34
+
35
+ ## Testing Restate service/object definitions
36
+
37
+ `restate.service({...})`/`restate.object({...})` do **not** return your handler functions
38
+ under `.handlers` — that property doesn't exist on the returned definition. The raw handler
39
+ functions are reachable at `.service` (for `restate.service`) or `.object` (for
40
+ `restate.object`), e.g. `cronJob.object.initiate(mockCtx, request)`. See `test/Cron.test.js`.
41
+
42
+ `@restatedev/restate-sdk-clients`'s `clients` export (re-exported from `lib/Admin.js`) is a
43
+ live ESM namespace binding — you cannot reassign `clients.connect` directly (`TypeError:
44
+ Attempted to assign to readonly property`). Use `mock.module('@restatedev/restate-sdk-clients',
45
+ () => ({...}))` instead, and capture the _real_ `connect` function once at module load (before
46
+ any mocking) if you need to restore it — reading it back off the live `clients` binding later
47
+ may observe an already-mocked value. See `test/Admin.test.js`.
48
+
49
+ `setupRestate` (in `lib/Admin.js`) is not unit tested: it binds real HTTP/2 + health-check
50
+ ports, installs process-wide `SIGTERM`/`SIGINT` handlers, and its returned `forceClose` calls
51
+ `process.exit()` — none of which are safe to exercise in-process in a test run.
52
+
53
+ ## Zero-dependency preference
54
+
55
+ Cron parsing uses `croner` (zero dependencies), not `cron-parser` (pulls in `luxon`). If you
56
+ touch `lib/Cron.js`'s scheduling logic: `new Cron(pattern)` without a callback just parses —
57
+ it does not start a timer — and `.nextRun(referenceDate)` is what gives a deterministic next
58
+ run time from Restate's replay-safe `ctx.date.now()`, matching the library's actual API rather
59
+ than `cron-parser`'s `CronExpressionParser.parse(...).next()` shape.
60
+
61
+ ## Style
62
+
63
+ - Formatting is enforced by oxfmt ([.oxfmtrc.json](./.oxfmtrc.json)): tabs, single quotes, no
64
+ semicolons, trailing commas. Run `bun run format:fix` before committing.
package/README.md ADDED
@@ -0,0 +1,78 @@
1
+ # @empyria/restate
2
+
3
+ [Restate.dev](https://restate.dev) helpers for **Principia**, a nanoservice framework built
4
+ primarily on Bun: an Admin API client, a generic dynamic-dispatch service, cron-driven
5
+ workflow scheduling, and Restate-aware input/output schema validation.
6
+
7
+ Targets Restate server `1.7.x` and `@restatedev/restate-sdk` `1.6.x`.
8
+
9
+ ## Requirements
10
+
11
+ - Bun `>=1.4.0` or Node.js `>=26`
12
+ - Plain ESM, no build step, no TypeScript
13
+
14
+ Both requirements come from [@empyria/classification](https://github.com/imrefazekas/empyria-classification)
15
+ and [@empyria/common](https://github.com/imrefazekas/empyria-common), which this package
16
+ depends on and which use the native `Temporal` global for all date/time handling.
17
+
18
+ ## Install
19
+
20
+ ```bash
21
+ bun add @empyria/restate
22
+ ```
23
+
24
+ ## Usage
25
+
26
+ ```js
27
+ import { createRestateAdmin, withValidation, cronJob, cronJobInitiator } from '@empyria/restate'
28
+
29
+ const admin = createRestateAdmin({
30
+ restateAdminURL: 'http://localhost:9070',
31
+ restateURL: 'http://localhost:9071',
32
+ })
33
+
34
+ const services = await admin.listServices()
35
+ ```
36
+
37
+ Everything is re-exported from the package root via [index.js](./index.js). Individual
38
+ modules under `lib/` can also be imported directly if you only need one:
39
+
40
+ ```js
41
+ import { checkServiceHandler } from '@empyria/restate/lib/Admin.js'
42
+ ```
43
+
44
+ ## Modules
45
+
46
+ | Module | Purpose |
47
+ | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
48
+ | [lib/Admin.js](./lib/Admin.js) | Restate Admin API client — service/handler discovery, deployment registration and teardown, workflow/message dispatch, and `setupRestate` for wiring up an endpoint with health checks and graceful shutdown. |
49
+ | [lib/Caller.js](./lib/Caller.js) | `CallerServiceDef` — a generic Restate service that dispatches a call to any handler on any other service by name, for when the target isn't known at compile time. |
50
+ | [lib/Cron.js](./lib/Cron.js) | `cronJobInitiator`/`cronJob` — Restate services implementing cron-driven, replay-safe recurring job scheduling on top of `croner`. |
51
+ | [lib/Validation.js](./lib/Validation.js) | `withValidation` — wraps a workflow handler with input/output JSON schema validation via `@empyria/common`. |
52
+
53
+ There is no official Restate Admin API client (verified directly against the published
54
+ `@restatedev/restate-sdk`/`-clients` packages) — `lib/Admin.js` is a hand-written wrapper kept
55
+ in sync with the live Admin API's OpenAPI spec (`<admin-url>/openapi`) by hand.
56
+
57
+ Every exported function is documented with JSDoc directly in its source file — hovering
58
+ a function in VSCode or Zed shows its parameters and return type without any extra
59
+ tooling, since both editors read JSDoc from plain `.js` files automatically.
60
+
61
+ Tests live under [test/](./test/), one file per module, separate from the sources. They
62
+ mock `fetch` and the Restate SDK client rather than requiring a live server — the one
63
+ exception is `setupRestate`, which binds real ports and installs process signal handlers
64
+ and is deliberately left untested (see [AGENTS.md](./AGENTS.md)).
65
+
66
+ ## Scripts
67
+
68
+ ```bash
69
+ bun run format # check formatting (oxfmt)
70
+ bun run format:fix # apply formatting
71
+ bun run lint # lint (oxlint)
72
+ bun run lint:fix # lint and fix
73
+ bun run test # run tests with coverage
74
+ ```
75
+
76
+ ## License
77
+
78
+ MIT © Imre Fazekas
package/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export * from './lib/Validation.js'
2
+
3
+ export * from './lib/Cron.js'
4
+
5
+ export * from './lib/Admin.js'
6
+
7
+ export * from './lib/Caller.js'