solid-objects 0.12.0 → 0.12.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"test-helper.d.ts","sourceRoot":"","sources":["../src/test-helper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAIvD,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,YAAY,CAAA;AAE9E,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,SAAS,cAAc,EAAE,CAAA;IACjC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAMD,qBAAa,sBAAsB;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,mBAAmB;IAEnD,KAAK,CAAC,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC;IA6B5D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,YAAY;CAUrB"}
1
+ {"version":3,"file":"test-helper.d.ts","sourceRoot":"","sources":["../src/test-helper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAIvD,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,YAAY,CAAA;AAE9E,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,SAAS,cAAc,EAAE,CAAA;IACjC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,GAAG,EAAE,IAAI,CAAA;IACT,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAMD,qBAAa,sBAAsB;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,mBAAmB;IAEnD,KAAK,CAAC,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC;IA6B5D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAIhB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,MAAM,CAAC;IAuBvE,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,YAAY;CAUrB"}
@@ -39,6 +39,30 @@ export class SolidObjectsTestHelper {
39
39
  reset() {
40
40
  return this.runtime.resetForTesting();
41
41
  }
42
+ async runDueReminders(options) {
43
+ const nowMilliseconds = options.now.getTime();
44
+ if (!Number.isFinite(nowMilliseconds)) {
45
+ throw new TypeError("reminder test time must be a valid date");
46
+ }
47
+ const maxReminders = options.maxReminders ?? 10_000;
48
+ if (!Number.isSafeInteger(maxReminders) || maxReminders < 1) {
49
+ throw new TypeError("maxReminders must be a positive safe integer");
50
+ }
51
+ const scheduler = this.runtime.reminderScheduler();
52
+ let processed = 0;
53
+ try {
54
+ while (processed < maxReminders) {
55
+ const count = await scheduler.runOnce({ now: options.now });
56
+ if (count === 0)
57
+ return processed;
58
+ processed += count;
59
+ }
60
+ return processed;
61
+ }
62
+ finally {
63
+ await scheduler.stop();
64
+ }
65
+ }
42
66
  defaultRoles() {
43
67
  const roles = ["reminders", "actors", "effects"];
44
68
  if (broadcastsEnabled(this.runtime.settings))
@@ -1 +1 @@
1
- {"version":3,"file":"test-helper.js","sourceRoot":"","sources":["../src/test-helper.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"test-helper.js","sourceRoot":"","sources":["../src/test-helper.ts"],"names":[],"mappings":"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"}
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "0.12.0";
1
+ export declare const VERSION = "0.12.1";
2
2
  //# sourceMappingURL=version.d.ts.map
package/dist/version.js CHANGED
@@ -1,2 +1,2 @@
1
- export const VERSION = "0.12.0";
1
+ export const VERSION = "0.12.1";
2
2
  //# sourceMappingURL=version.js.map
package/docs/api.md CHANGED
@@ -31,6 +31,30 @@ generic signatures; this index explains the supported role of every export.
31
31
  `PayloadBroadcasts`, and `PayloadBroadcastValue` describe actor-declared
32
32
  transactional work and typed personalized projections.
33
33
 
34
+ `MessageReference` does not retain an invocation's authorization context.
35
+ Supply `authorizationContext` to each `status()`, `result()`, and `wait()` call;
36
+ the runtime reauthorizes the persisted operation every time. Durable results
37
+ are JSON, so an operation that returns `undefined` or is declared `void`
38
+ resolves as `null`.
39
+
40
+ Declare named payload return shapes with a `type` alias rather than an
41
+ `interface`. `PayloadBroadcastValue` requires the implicit string index
42
+ signature of a JSON object, which TypeScript gives object type aliases but not
43
+ interfaces.
44
+
45
+ Snapshots return `DeepReadonly`, so application helpers should accept readonly
46
+ structure rather than cast it away. A helper that only needs a session ID can
47
+ preserve its useful result type with a generic boundary:
48
+
49
+ ```typescript
50
+ function playerForSession<PlayerType extends { sessionId: string }>(options: {
51
+ room: { readonly players: readonly PlayerType[] }
52
+ sessionId: string | null
53
+ }): PlayerType | undefined {
54
+ return options.room.players.find((player) => player.sessionId === options.sessionId)
55
+ }
56
+ ```
57
+
34
58
  ### Runtime managers
35
59
 
36
60
  Every manager below is available as a property on `SolidObjectsRuntime`; the
@@ -48,7 +72,7 @@ class and result types are also exported for integration typing.
48
72
  - `runtime.doctor` / `Doctor`: `run({ roundTrip })` structured installation
49
73
  report.
50
74
  - `runtime.testing` / `SolidObjectsTestHelper`: deterministic `drain()` and
51
- dependency-ordered `reset()`.
75
+ explicit-time `runDueReminders()`, plus dependency-ordered `reset()`.
52
76
  - `runtime.realtime` / `RealtimeManager`: `connect()`, process-local
53
77
  `publish()`, and `close()`.
54
78
 
@@ -60,11 +84,16 @@ The manager types are `DeadLetter`; `ReminderPage`, `ReminderPageOptions`,
60
84
  `QuietReconciliationOptions`, `ReconciliationInstance`, `ReconciliationPage`,
61
85
  `ReconciliationPageOptions`, and `ReconciliationStatesOptions`;
62
86
  `RetentionOptions`, `RetentionResult`, and `RetentionTarget`; and
63
- `TestDrainOptions` and `TestHelperRole`. `RealtimeConnectionOptions`,
87
+ `RunDueRemindersOptions`, `TestDrainOptions`, and `TestHelperRole`.
88
+ `RealtimeConnectionOptions`,
64
89
  `RealtimeSession`, and `SubscriptionRequest` define the server session API.
65
90
  `AdministrationOptions` carries the application-owned authorization context
66
91
  for administration calls.
67
92
 
93
+ `ProcessRecord.shutdownState` is `"running"`, `"draining"`, or `"stopped"`;
94
+ there is no separate `running` field. `RetentionResult.count` means eligible
95
+ rows for `preview()` and rows actually deleted for `prune()`.
96
+
68
97
  ### Registration and integration
69
98
 
70
99
  - `runtime.register(ActorClass)`: validate and register an actor definition.
@@ -72,7 +101,9 @@ for administration calls.
72
101
  isolated runtime.
73
102
  - `runtime.registerEffect(name, handler)`: register an at-least-once external
74
103
  effect handler. `EffectContext` carries the stable effect ID and source
75
- identity.
104
+ identity. Success operations receive `{ effectId, arguments, result }` and
105
+ failure operations receive `{ effectId, arguments, error }`; `arguments` is
106
+ the JSON object originally staged by `emit()`.
76
107
  - `runtime.registerCommitAction(name, handler)`: register a same-database
77
108
  fenced transaction handler. `CommitActionContext` includes the active
78
109
  `DatabaseConnection`.
@@ -134,7 +165,8 @@ The root exports `SolidObjectsError` and its supported subclasses:
134
165
  - admission and payload failures: `MailboxFull`, `InvalidPayload`,
135
166
  `PayloadTooLarge`, `IdempotencyConflict`, `InvalidPayloadBroadcast`, and
136
167
  `UnknownPayloadBroadcast`;
137
- - definition and execution failures: `InvalidActor`, `UnknownActorType`,
168
+ - definition and execution failures: `InvalidActor`, `InvalidRejectionCode`,
169
+ `UnknownActorType`,
138
170
  `UnknownOperation`, `ActorCallCycle`, `QueryMutatedState`,
139
171
  `StateMigrationError`, `ApplicationWriteForbidden`, `UnknownEffect`, and
140
172
  `UnknownCommitAction`;
@@ -5,6 +5,13 @@ subscription requests and receives JSON invalidation envelopes over WebSocket.
5
5
  The application supplies the rendering callback and authenticated WebSocket
6
6
  server; `runtime.realtime` supplies the server-side session protocol.
7
7
 
8
+ The `observables` object contains values, not only invalidation names, and every
9
+ subscriber authorized for that actor receives the same projection. This differs
10
+ from Ruby morph components, which re-fetch a signed endpoint without putting
11
+ observable values on the wire. Keep secrets and subscriber-specific state out
12
+ of `observables()`; use personalized payloads or an application endpoint that
13
+ reauthorizes the component request.
14
+
8
15
  The 0.1 subscription request is:
9
16
 
10
17
  ```json
@@ -96,6 +96,25 @@ server.
96
96
 
97
97
  ## Database adapters
98
98
 
99
+ ### Database value mapping
100
+
101
+ `DatabaseConnection.get<Row>()` and `all<Row>()` trust the caller-supplied row
102
+ type; they do not validate or convert driver results. Type rows to the adapter's
103
+ runtime representation or normalize them at the application boundary.
104
+
105
+ | SQL value | SQLite (`node:sqlite`) | PostgreSQL (`pg`) | MySQL (`mysql2`) |
106
+ | ----------------------------------- | --------------------------- | ----------------------------------------------- | ----------------------------------- |
107
+ | ordinary integer | `bigint` | `number` for `int2`/`int4`; `bigint` for `int8` | `number` for ordinary integer types |
108
+ | arbitrary precision integer/decimal | `bigint` for SQLite INTEGER | `numeric` remains the driver's decimal string | `BIGINT` and `DECIMAL` are strings |
109
+ | floating point | `number` | `number` | `number` |
110
+ | text | `string` | `string` | `string` |
111
+ | binary | `Uint8Array` | `Buffer` | `Buffer` |
112
+ | null | `null` | `null` | `null` |
113
+
114
+ `RunResult.changes` is always a `number`. `lastInsertId`, when an adapter
115
+ provides it, is a decimal `string`; SQLite and MySQL set it for nonzero generated
116
+ IDs, while PostgreSQL callers should use `RETURNING` with `get()`.
117
+
99
118
  ### SQLite
100
119
 
101
120
  `sqlite({ path, timeoutMilliseconds = 5_000, lockRetryAttempts = 10 })` uses
@@ -19,11 +19,18 @@ do not parse error messages.
19
19
  | `PayloadTooLarge` | Arguments, state, result, snapshot getter, effect result, or personalized payload exceeded its configured limit. | Reduce the JSON value or deliberately raise the corresponding limit. |
20
20
  | `SyncInsideTransaction` | A committed call or message wait would self-deadlock inside this adapter's transaction. | Finish the transaction first or stage actor-owned work through a commit action. |
21
21
 
22
+ `this.reject()` accepts codes matching `[A-Za-z_][A-Za-z0-9_]*`, including
23
+ camelCase. An invalid code throws the non-retryable `InvalidRejectionCode`; the
24
+ operation fails on its first attempt and a synchronous caller receives
25
+ `MessageFailed` instead of waiting through retry backoff.
26
+
22
27
  `MessageReference.status()`, `result()`, and `wait()` reauthorize the stored
23
28
  operation. `result()` returns `undefined` while work is nonterminal, returns the
24
29
  committed result when complete, and raises `Rejected` or `MessageFailed` for a
25
30
  terminal refusal or failure. `wait()` blocks until the same terminal outcomes
26
- or its deadline.
31
+ or its deadline. A reference does not retain the authorization context used to
32
+ send it; supply the context to each of these methods so the stored operation is
33
+ reauthorized.
27
34
 
28
35
  ## Definition and programming errors
29
36
 
@@ -31,6 +38,8 @@ These errors normally require a code or deployment correction:
31
38
 
32
39
  - `InvalidActor`: invalid actor type, state version, migration declaration,
33
40
  member name, payload declaration, or duplicate registration.
41
+ - `InvalidRejectionCode`: `reject()` received a code outside the supported
42
+ identifier grammar. It is terminal because retrying cannot change actor code.
34
43
  - `UnknownActorType`, `UnknownOperation`, `UnknownEffect`, and
35
44
  `UnknownCommitAction`: deployed registration does not match durable work or
36
45
  code attempted an undeclared operation.
@@ -87,3 +96,9 @@ linked replacement message; repeating the call returns the same replacement.
87
96
 
88
97
  Effects are different: they execute outside the actor transaction and are at
89
98
  least once. Deduplicate external work with the stable `EffectContext.id`.
99
+ Success and failure callback operations receive the originally staged
100
+ `arguments` for actor-state correlation. A retryable failure scheduled into the
101
+ future is correctly considered idle for the present pass, so
102
+ `runtime.testing.drain()` does not advance retry backoff; use a
103
+ `NonRetryableError` when a test needs to exercise the exhausted failure callback
104
+ without waiting.
package/docs/parity.md CHANGED
@@ -6,7 +6,7 @@ not copying a Rails API into Node.
6
6
 
7
7
  Reference: Ruby `solid_objects` 0.12.0 at commit `a01b6f5`.
8
8
 
9
- The Node `0.12.0` implementation has spiritual parity with that reference. Its
9
+ The Node `0.12.1` implementation has spiritual parity with that reference. Its
10
10
  relational runtime, correctness boundaries, administration, diagnostics,
11
11
  realtime projections, browser behavior, and supported adapters have native
12
12
  equivalents. Rails engine and rendering surfaces are intentionally replaced by
@@ -32,11 +32,11 @@ missing Ruby capabilities.
32
32
  | Actor registry, durable identity, JSON state, and adjacent state migrations | Native | Ordinary classes, static actor types, inferred state, explicit migrations, and isolated runtime context across every actor-instance callback. |
33
33
  | Fluent committed calls and background delivery | Native | `await reference.operation()` and `reference.send.operation()`. |
34
34
  | Ordered mailbox, sequence allocation, idempotency, retries, dead letters, leases, renewal, and fenced commits | Native | Relational ready/claimed membership tables, distinct generated request IDs and caller idempotency keys, durable history, and adapter-appropriate sequence locking. |
35
- | Domain rejection and strict poison ordering | Native | Rejections roll back without retry; retryable failures block later operations until completion or dead-lettering. |
35
+ | Domain rejection and strict poison ordering | Native | Rejections accept JavaScript identifier-style codes and roll back without retry; invalid codes fail terminally, while retryable failures block later operations until completion or dead-lettering. |
36
36
  | Bounded activation passes and hot-actor fairness | Native | Configurable turn-count and elapsed-time budgets bound each pass, then move only that actor's already-due memberships behind actors already waiting. |
37
37
  | Bounded claim candidate scan | Native | A configurable ordered scan continues to another ready actor when a worker loses the first candidate's lease race. |
38
38
  | Idle activation cache | Native | Long-running workers retain hydrated actors under renewable fenced leases, restore public state after failed turns, and release on timeout, fairness yield, lease loss, or shutdown. |
39
- | Transactional effects and outcome operations | Native | At-least-once handlers receive immutable stable effect, attempt, source-message, and actor identity; success and failure return through actor operations. |
39
+ | Transactional effects and outcome operations | Native | At-least-once handlers receive immutable stable effect, attempt, source-message, and actor identity; success and failure operations also receive the originally staged arguments for correlation. |
40
40
  | Actor-to-actor delivery | Native | `sendTo(reference).operation()` stages delivery in the source actor commit. |
41
41
  | One-shot and recurring reminders | Native | Scheduling, replacement events, catch-up policy, stale-claim recovery, pausing, authorized inspection, and idempotent resume are implemented. |
42
42
  | Same-database commit actions | Native | Registered actions receive source-message identity, mailbox sequence, activation generation, and the fenced transaction connection. |
@@ -60,7 +60,7 @@ missing Ruby capabilities.
60
60
  | Doctor and schema verification | Native | Structured checks cover configuration, schema/version shape, adapter server versions, neutral-context policy probes, live roles, and a targeted round trip. |
61
61
  | CLI | Native | The packaged executable loads an application runtime and exposes start, diagnostics, processes, dead letters, reminders, and explicit retention pruning as JSON. |
62
62
  | Structured instrumentation | Native | An isolated transport-neutral sink emits immutable lifecycle metadata and structurally excludes application payloads. |
63
- | Public test helper | Native | `runtime.testing` provides role-selective deterministic draining and dependency-ordered reset without relying on cascades. |
63
+ | Public test helper | Native | `runtime.testing` provides role-selective deterministic draining, explicit-time due-reminder execution, and dependency-ordered reset without relying on cascades. |
64
64
 
65
65
  ## Databases and wake-up
66
66
 
@@ -76,15 +76,15 @@ missing Ruby capabilities.
76
76
 
77
77
  ## Realtime and browser behavior
78
78
 
79
- | Capability | Status | TypeScript shape or remaining work |
80
- | ------------------------------------------------------------ | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
81
- | Explicit observable projection and durable invalidations | Native | `observables()` is opt-in; only changed projected values enter the broadcast outbox. |
82
- | Action Cable channels and signed stream names | Not applicable | `runtime.realtime` provides authenticated transport-neutral sessions; the host owns its HTTP/WebSocket server and authentication. |
83
- | Authorized subscriptions | Native | Each request is denied by default and authorized before actor lookup; sessions replay committed observables and fence ordered durable revisions. Multi-process hosts explicitly bridge their shared transport. |
84
- | Turbo scalar replacement | Not applicable | The browser client exposes invalidations to application rendering code. Framework adapters can be separate packages. |
85
- | Keyed component refresh, morph/replace, and batch coalescing | Native | A typed framework-neutral registry selects explicit dependencies, coalesces batch requests, aborts superseded work, fences each target, and delegates synchronous application strategy to the host. |
86
- | Personalized payload broadcasts | Native | Static typed projections run against committed state under each fresh subscriber context, reauthorize as queries, isolate failures, and carry independent revision fences. |
87
- | Real-browser compatibility suite | Native | Playwright exercises subscription replay over native WebSocket, incarnation/revision fences, payload delivery, component batching, and cancellation in Chromium. |
79
+ | Capability | Status | TypeScript shape or remaining work |
80
+ | ------------------------------------------------------------ | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
81
+ | Explicit observable projection and durable invalidations | Native | `observables()` is opt-in; changed values enter invalidation envelopes and are visible to every authorized subscriber. Unlike Ruby morph refreshes, values cross the wire, so private or subscriber-specific state belongs in payloads or reauthorized component endpoints. |
82
+ | Action Cable channels and signed stream names | Not applicable | `runtime.realtime` provides authenticated transport-neutral sessions; the host owns its HTTP/WebSocket server and authentication. |
83
+ | Authorized subscriptions | Native | Each request is denied by default and authorized before actor lookup; sessions replay committed observables and fence ordered durable revisions. Multi-process hosts explicitly bridge their shared transport. |
84
+ | Turbo scalar replacement | Not applicable | The browser client exposes invalidations to application rendering code. Framework adapters can be separate packages. |
85
+ | Keyed component refresh, morph/replace, and batch coalescing | Native | A typed framework-neutral registry selects explicit dependencies, coalesces batch requests, aborts superseded work, fences each target, and delegates synchronous application strategy to the host. |
86
+ | Personalized payload broadcasts | Native | Static typed projections run against committed state under each fresh subscriber context, reauthorize as queries, isolate failures, and carry independent revision fences. |
87
+ | Real-browser compatibility suite | Native | Playwright exercises subscription replay over native WebSocket, incarnation/revision fences, payload delivery, component batching, and cancellation in Chromium. |
88
88
 
89
89
  ## Rails-specific surfaces
90
90
 
package/docs/releasing.md CHANGED
@@ -26,8 +26,9 @@ npm trust github solid-objects \
26
26
 
27
27
  ## Release procedure
28
28
 
29
- 1. Update the version in `package.json` and `pnpm-lock.yaml` and move the
30
- release notes out of the Unreleased section in `CHANGELOG.md`.
29
+ 1. Update the version in `package.json` and `src/version.ts`, refresh the
30
+ lockfile when needed, and move the release notes out of the Unreleased
31
+ section in `CHANGELOG.md`.
31
32
  2. Run `pnpm run format:check`, `pnpm run check`, `pnpm run test:coverage`,
32
33
  `pnpm run build`, `pnpm run pack:check`, and
33
34
  `pnpm audit --audit-level=high`.
@@ -35,8 +36,8 @@ npm trust github solid-objects \
35
36
  4. Create and push an annotated tag matching the package version:
36
37
 
37
38
  ```shell
38
- git tag -a v0.13.0 -m "Version 0.13.0"
39
- git push origin v0.13.0
39
+ git tag -a v0.12.1 -m "Version 0.12.1"
40
+ git push origin v0.12.1
40
41
  ```
41
42
 
42
43
  The tag runs the complete CI matrix. The publish job starts only after every
@@ -116,10 +116,10 @@ crash, so it cannot establish correctness.
116
116
  ## Domain rejection and failure
117
117
 
118
118
  Call `this.reject(code, { message, details })` when an operation is valid but
119
- the domain refuses it. Codes contain lowercase letters, digits, and
120
- underscores. The turn rolls back, staged work is discarded, the message becomes
121
- `rejected`, and later mailbox work remains eligible. The caller receives
122
- `Rejected` with the code, frozen JSON details, and durable message ID.
119
+ the domain refuses it. Codes use the same identifier rule as actor members:
120
+ `[A-Za-z_][A-Za-z0-9_]*`. The turn rolls back, staged work is discarded, the
121
+ message becomes `rejected`, and later mailbox work remains eligible. The caller
122
+ receives `Rejected` with the code, frozen JSON details, and durable message ID.
123
123
 
124
124
  Throwing another error rolls the turn back and schedules a retry according to
125
125
  `maxAttempts` and `retryDelayMilliseconds`. Throw a custom subclass of
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "solid-objects",
3
- "version": "0.12.0",
3
+ "version": "0.12.1",
4
4
  "description": "Durable, addressable objects for Node.js",
5
5
  "type": "module",
6
6
  "license": "MIT",