@twoabove/cue 0.4.7 → 0.5.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.
- package/README.md +76 -4
- package/dist/api/create.d.ts.map +1 -1
- package/dist/api/create.js +16 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/runtime/Entity.d.ts +2 -1
- package/dist/runtime/Entity.d.ts.map +1 -1
- package/dist/runtime/Entity.js +72 -35
- package/dist/stream/constants.d.ts +3 -0
- package/dist/stream/constants.d.ts.map +1 -0
- package/dist/stream/constants.js +2 -0
- package/dist/stream/index.d.ts +4 -0
- package/dist/stream/index.d.ts.map +1 -0
- package/dist/stream/index.js +2 -0
- package/dist/stream/reader.d.ts +5 -0
- package/dist/stream/reader.d.ts.map +1 -0
- package/dist/stream/reader.js +67 -0
- package/dist/stream/types.d.ts +44 -0
- package/dist/stream/types.d.ts.map +1 -0
- package/dist/stream/types.js +1 -0
- package/dist/types/public.d.ts +9 -1
- package/dist/types/public.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -31,7 +31,7 @@ console.log(await counter.read.value()); // 5
|
|
|
31
31
|
- **Durable.** State survives restarts. Plug in Postgres, SQLite, or Redis—or run in-memory for tests.
|
|
32
32
|
- **Safe.** One operation at a time, always. No race conditions, no corrupted state.
|
|
33
33
|
- **Evolvable.** Schema changes are type-checked and automatic. Add a field, rename a property—old entities migrate on load.
|
|
34
|
-
- **Streamable.** Long-running operations yield progress in real-time.
|
|
34
|
+
- **Streamable.** Long-running operations yield progress in real-time. Streams survive client disconnects—reconnect and resume where you left off.
|
|
35
35
|
- **Time-travel.** Query historical state at any point with full type safety.
|
|
36
36
|
|
|
37
37
|
## Installation
|
|
@@ -146,7 +146,7 @@ const ref = manager.get("entity-id");
|
|
|
146
146
|
|
|
147
147
|
await ref.send.someCommand(); // Execute a command (may modify state)
|
|
148
148
|
await ref.read.someQuery(); // Execute a query (read-only)
|
|
149
|
-
ref.stream.streamingCommand(); //
|
|
149
|
+
const run = ref.stream.streamingCommand(); // StreamRun with .id for reconnection
|
|
150
150
|
await ref.snapshot(); // Get current state and version
|
|
151
151
|
await ref.stateAt(version); // Get historical state at a specific event version
|
|
152
152
|
await ref.stop(); // Manually stop this entity
|
|
@@ -186,6 +186,50 @@ const Entity = define("Entity")
|
|
|
186
186
|
.build();
|
|
187
187
|
```
|
|
188
188
|
|
|
189
|
+
## Durable Streams
|
|
190
|
+
|
|
191
|
+
When persistence is enabled, streams automatically record every yielded value. If a client disconnects mid-stream - browser refresh, network blip, mobile app backgrounded - the stream keeps running on the server. The client reconnects and picks up exactly where it left off. No lost data, no restarting from scratch.
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
// Start a long-running operation
|
|
195
|
+
const run = ref.stream.generateReport(params);
|
|
196
|
+
|
|
197
|
+
// Return the stream ID to the client immediately
|
|
198
|
+
res.json({ streamId: run.id });
|
|
199
|
+
|
|
200
|
+
// Stream continues in the background, persisting each chunk
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
The client consumes live or reconnects later:
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
// First connection: consume live
|
|
207
|
+
for await (const { seq, data } of manager.readStream(streamId)) {
|
|
208
|
+
render(data);
|
|
209
|
+
lastSeq = seq; // Track position for reconnection
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// After disconnect: resume from last position
|
|
213
|
+
for await (const { seq, data } of manager.readStream(streamId, { after: lastSeq })) {
|
|
214
|
+
render(data);
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Check stream status without consuming:
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
const status = await manager.streamStatus(streamId);
|
|
222
|
+
// { state: 'running', seq: 42n }
|
|
223
|
+
// { state: 'complete', seq: 100n, returnValue: { report: ... } }
|
|
224
|
+
// { state: 'error', seq: 50n, error: 'timeout' }
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
The `returnValue` field contains the generator's return value once complete.
|
|
228
|
+
|
|
229
|
+
**Note:** The entity is locked during stream execution (one operation at a time). Other commands to the same entity will queue until the stream finishes. This ensures consistency but means long streams block other operations on that entity.
|
|
230
|
+
|
|
231
|
+
This is essential for AI assistants, file processors, report generators - any operation that takes longer than a network timeout.
|
|
232
|
+
|
|
189
233
|
## Schema Evolution
|
|
190
234
|
|
|
191
235
|
Migrate entity state without downtime:
|
|
@@ -354,6 +398,25 @@ Under the hood, Cue uses **event sourcing**. Every state change is recorded as a
|
|
|
354
398
|
|
|
355
399
|
But you don't need to think about events. Write mutations directly—Cue captures them automatically via Immer.
|
|
356
400
|
|
|
401
|
+
## On Persistence Complexity
|
|
402
|
+
|
|
403
|
+
Cue doesn't force a specific persistence provider. You implement `PersistenceAdapter` for whatever database you have. This flexibility adds some decision-making, but most applications won't need anything complicated.
|
|
404
|
+
|
|
405
|
+
**PostgreSQL handles more than you think:**
|
|
406
|
+
|
|
407
|
+
| Workload | PostgreSQL (single instance) |
|
|
408
|
+
| -------- | ---------------------------- |
|
|
409
|
+
| < 500 events/sec | Comfortable, no tuning needed |
|
|
410
|
+
| 500 - 2,000 events/sec | Add connection pooling |
|
|
411
|
+
| 2,000 - 5,000 events/sec | Tune indexes, batch writes, consider read replicas |
|
|
412
|
+
| > 5,000 events/sec | Time to think about Redis or sharding |
|
|
413
|
+
|
|
414
|
+
These are rough estimates for a typical cloud database. Your mileage varies with hardware, event size, and query patterns.
|
|
415
|
+
|
|
416
|
+
**Redis is powerful but often unnecessary.** Redis Streams map beautifully to Cue's event model - fast writes, blocking reads for live streaming, built-in consumer groups. But remember: Cue already keeps hot entities in memory. The EntityManager holds active entities, passivation evicts idle ones. Your database only sees hydration reads and event writes, not every state access.
|
|
417
|
+
|
|
418
|
+
For most applications - even busy ones - PostgreSQL with snapshotting enabled is plenty. Add Redis when you have evidence you need it, not before.
|
|
419
|
+
|
|
357
420
|
## API Reference
|
|
358
421
|
|
|
359
422
|
### `define(name)`
|
|
@@ -391,16 +454,25 @@ const ref = manager.get("id");
|
|
|
391
454
|
|
|
392
455
|
ref.send.command(...args); // Execute command, returns Promise
|
|
393
456
|
ref.read.query(...args); // Execute query, returns Promise
|
|
394
|
-
ref.stream.command(...args); // Returns
|
|
457
|
+
ref.stream.command(...args); // Returns StreamRun<T> with .id, .seq, .isLive
|
|
395
458
|
ref.snapshot(); // Returns Promise<{ state, version }>
|
|
396
459
|
ref.stateAt(eventVersion); // Returns Promise<{ schemaVersion, state }>
|
|
397
460
|
ref.stop(); // Stop and release this entity
|
|
398
461
|
```
|
|
399
462
|
|
|
463
|
+
### `EntityManager`
|
|
464
|
+
|
|
465
|
+
```typescript
|
|
466
|
+
manager.get("id"); // Get or create entity reference
|
|
467
|
+
manager.readStream(streamId, { after? }); // Read durable stream by ID
|
|
468
|
+
manager.streamStatus(streamId); // Get stream state without consuming
|
|
469
|
+
manager.stop(); // Shut down all entities
|
|
470
|
+
```
|
|
471
|
+
|
|
400
472
|
### Type Utilities
|
|
401
473
|
|
|
402
474
|
```typescript
|
|
403
|
-
import { HistoryOf, VersionState, StateOf } from "@twoabove/cue";
|
|
475
|
+
import { HistoryOf, VersionState, StateOf, StreamRun, StreamStatus } from "@twoabove/cue";
|
|
404
476
|
|
|
405
477
|
type History = HistoryOf<typeof Entity>; // Discriminated union of all versions
|
|
406
478
|
type V2State = VersionState<typeof Entity, 2>; // State type at schema version 2
|
package/dist/api/create.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/api/create.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/api/create.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,mBAAmB,EACnB,aAAa,EACb,mBAAmB,EAUpB,MAAM,iBAAiB,CAAC;AAEzB,wBAAgB,MAAM,CAAC,IAAI,SAAS,mBAAmB,EACrD,MAAM,EAAE,mBAAmB,CAAC,IAAI,CAAC,GAChC,aAAa,CAAC,IAAI,CAAC,CAwKrB"}
|
package/dist/api/create.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ManagerShutdownError } from "../errors";
|
|
2
2
|
import { RuntimeEntityManager } from "../runtime/EntityManager";
|
|
3
|
+
import { readStream, streamStatus } from "../stream/reader";
|
|
3
4
|
export function create(config) {
|
|
4
5
|
const manager = new RuntimeEntityManager(config);
|
|
5
6
|
const entries = new Map();
|
|
@@ -57,7 +58,9 @@ export function create(config) {
|
|
|
57
58
|
return {
|
|
58
59
|
get(id) {
|
|
59
60
|
const existing = entries.get(id);
|
|
60
|
-
if (existing &&
|
|
61
|
+
if (existing &&
|
|
62
|
+
!existing.entity.isFailed &&
|
|
63
|
+
!existing.entity.isShutdown) {
|
|
61
64
|
return existing.ref;
|
|
62
65
|
}
|
|
63
66
|
let entity = manager.getEntity(id);
|
|
@@ -101,6 +104,18 @@ export function create(config) {
|
|
|
101
104
|
entries.set(id, entry);
|
|
102
105
|
return ref;
|
|
103
106
|
},
|
|
107
|
+
readStream(streamId, options) {
|
|
108
|
+
if (!config.store) {
|
|
109
|
+
throw new Error("readStream requires a persistence store");
|
|
110
|
+
}
|
|
111
|
+
return readStream(config.store, streamId, options);
|
|
112
|
+
},
|
|
113
|
+
async streamStatus(streamId) {
|
|
114
|
+
if (!config.store) {
|
|
115
|
+
throw new Error("streamStatus requires a persistence store");
|
|
116
|
+
}
|
|
117
|
+
return streamStatus(config.store, streamId);
|
|
118
|
+
},
|
|
104
119
|
stop: () => manager.terminate(),
|
|
105
120
|
};
|
|
106
121
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export type { Draft, Immutable } from "immer";
|
|
|
2
2
|
export * from "./api/index";
|
|
3
3
|
export * from "./errors/index";
|
|
4
4
|
export type * from "./persistence/types";
|
|
5
|
+
export type { ReadStreamOptions, StreamChunk, StreamReader, StreamRun, StreamStatus, } from "./stream/types";
|
|
5
6
|
export { _handlers, _initialStateFn, _messages, _name, _persistence, _state, _tag, _upcasters, _versions, } from "./types/internal";
|
|
6
7
|
export type * from "./types/public";
|
|
7
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC9C,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,mBAAmB,qBAAqB,CAAC;AACzC,OAAO,EACL,SAAS,EACT,eAAe,EACf,SAAS,EACT,KAAK,EACL,YAAY,EACZ,MAAM,EACN,IAAI,EACJ,UAAU,EACV,SAAS,GACV,MAAM,kBAAkB,CAAC;AAC1B,mBAAmB,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC9C,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,mBAAmB,qBAAqB,CAAC;AACzC,YAAY,EACV,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,SAAS,EACT,YAAY,GACb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,SAAS,EACT,eAAe,EACf,SAAS,EACT,KAAK,EACL,YAAY,EACZ,MAAM,EACN,IAAI,EACJ,UAAU,EACV,SAAS,GACV,MAAM,kBAAkB,CAAC;AAC1B,mBAAmB,gBAAgB,CAAC"}
|
package/dist/runtime/Entity.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { PersistenceAdapter } from "../persistence/types";
|
|
2
|
+
import type { StreamRun } from "../stream/types";
|
|
2
3
|
import type { AnyEntityDefinition, EntityMetrics, Supervisor } from "../types/public";
|
|
3
4
|
import type { Clock } from "../utils/clock";
|
|
4
5
|
export declare class Entity<TState extends object> {
|
|
@@ -21,7 +22,7 @@ export declare class Entity<TState extends object> {
|
|
|
21
22
|
get lastActivity(): number;
|
|
22
23
|
tell: (handlerName: string, args: unknown[]) => Promise<unknown>;
|
|
23
24
|
ask: (handlerName: string, args: unknown[]) => Promise<unknown>;
|
|
24
|
-
stream: (handlerName: string, args: unknown[]) =>
|
|
25
|
+
stream: (handlerName: string, args: unknown[]) => StreamRun<unknown>;
|
|
25
26
|
inspect: () => Promise<{
|
|
26
27
|
state: TState;
|
|
27
28
|
version: bigint;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Entity.d.ts","sourceRoot":"","sources":["../../src/runtime/Entity.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAEV,kBAAkB,EAEnB,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"Entity.d.ts","sourceRoot":"","sources":["../../src/runtime/Entity.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAEV,kBAAkB,EAEnB,MAAM,sBAAsB,CAAC;AAM9B,OAAO,KAAK,EAGV,SAAS,EACV,MAAM,iBAAiB,CAAC;AAQzB,OAAO,KAAK,EACV,mBAAmB,EACnB,aAAa,EAEb,UAAU,EACX,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAQ5C,qBAAa,MAAM,CAAC,MAAM,SAAS,MAAM;aASrB,EAAE,EAAE,MAAM;IAC1B,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;IACvB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;IAC5B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAdxB,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,KAAK,CAAC,CAAQ;IACtB,OAAO,CAAC,gBAAgB,CAAC,CAAgB;gBAGvB,EAAE,EAAE,MAAM,EACT,GAAG,EAAE,mBAAmB,EACxB,SAAS,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,kBAAkB,YAAA,EAC1B,UAAU,CAAC,EAAE,UAAU,YAAA,EACvB,OAAO,CAAC,EAAE,aAAa,YAAA,EACvB,KAAK,GAAE,KAAiB;IAM3C,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,IAAI,UAAU,IAAI,OAAO,CAExB;IAED,IAAI,YAAY,IAAI,MAAM,CAEzB;IAEM,IAAI,GAAI,aAAa,MAAM,EAAE,MAAM,OAAO,EAAE,KAAG,OAAO,CAAC,OAAO,CAAC,CA6DpE;IAEK,GAAG,GAAI,aAAa,MAAM,EAAE,MAAM,OAAO,EAAE,KAAG,OAAO,CAAC,OAAO,CAAC,CAKnE;IAEK,MAAM,GACX,aAAa,MAAM,EACnB,MAAM,OAAO,EAAE,KACd,SAAS,CAAC,OAAO,CAAC,CAsInB;IAEK,OAAO,QAAa,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAMpE;IAEK,SAAS,QAAa,OAAO,CAAC,IAAI,CAAC,CAKxC;IAEK,OAAO,GACZ,eAAe,MAAM,KACpB,OAAO,CAAC;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC,CA8CnD;YAEY,MAAM;YAkCN,YAAY;YASZ,OAAO;IAgER,aAAa,CAAC,KAAK,UAAQ;IA0BxC,OAAO,CAAC,OAAO,CAOb;IAEF,OAAO,CAAC,MAAM,CAIZ;IAEF,OAAO,CAAC,YAAY;CAOrB"}
|
package/dist/runtime/Entity.js
CHANGED
|
@@ -3,8 +3,10 @@ import { Evolution } from "../core/Evolution";
|
|
|
3
3
|
import { StateKernel } from "../core/StateKernel";
|
|
4
4
|
import { CommitError, DefinitionMismatchError, HydrationError, OutOfOrderEventsError, StoppedEntityError, } from "../errors";
|
|
5
5
|
import { clone, deserialize, serialize } from "../serde";
|
|
6
|
+
import { STREAM_ENTITY_DEF_NAME, STREAM_SCHEMA_VERSION, } from "../stream/constants";
|
|
6
7
|
import { _handlers, _initialStateFn, _name, _persistence, _upcasters, } from "../types/internal";
|
|
7
8
|
import { WallClock } from "../utils/clock";
|
|
9
|
+
import { newId } from "../utils/id";
|
|
8
10
|
import { Mailbox } from "./Mailbox";
|
|
9
11
|
import { Supervise } from "./Supervision";
|
|
10
12
|
export class Entity {
|
|
@@ -87,13 +89,13 @@ export class Entity {
|
|
|
87
89
|
});
|
|
88
90
|
};
|
|
89
91
|
stream = (handlerName, args) => {
|
|
90
|
-
// Stream holds the mailbox for its entire duration to prevent interleaved
|
|
91
|
-
// commands from causing state overwrites when the stream commits.
|
|
92
92
|
const self = this;
|
|
93
|
+
const streamId = `${this.id}:${handlerName}:${newId()}`;
|
|
93
94
|
const channel = [];
|
|
94
95
|
let consumerWaiting = null;
|
|
95
|
-
let
|
|
96
|
-
let
|
|
96
|
+
let currentSeq = 0n;
|
|
97
|
+
let isLive = true;
|
|
98
|
+
let producerDone = false;
|
|
97
99
|
function push(item) {
|
|
98
100
|
if (consumerWaiting) {
|
|
99
101
|
const resolve = consumerWaiting;
|
|
@@ -112,63 +114,98 @@ export class Entity {
|
|
|
112
114
|
consumerWaiting = resolve;
|
|
113
115
|
});
|
|
114
116
|
}
|
|
115
|
-
function
|
|
116
|
-
if (
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
117
|
+
async function commitStreamChunk(value) {
|
|
118
|
+
if (!self.store)
|
|
119
|
+
return;
|
|
120
|
+
currentSeq += 1n;
|
|
121
|
+
const envelope = {
|
|
122
|
+
entityDefName: STREAM_ENTITY_DEF_NAME,
|
|
123
|
+
schemaVersion: STREAM_SCHEMA_VERSION,
|
|
124
|
+
handler: "chunk",
|
|
125
|
+
payload: [value],
|
|
126
|
+
patches: [],
|
|
127
|
+
};
|
|
128
|
+
await self.store.commitEvent(streamId, currentSeq, serialize(envelope));
|
|
121
129
|
}
|
|
122
|
-
function
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
130
|
+
async function commitStreamEnd(payload) {
|
|
131
|
+
if (!self.store)
|
|
132
|
+
return;
|
|
133
|
+
currentSeq += 1n;
|
|
134
|
+
const envelope = {
|
|
135
|
+
entityDefName: STREAM_ENTITY_DEF_NAME,
|
|
136
|
+
schemaVersion: STREAM_SCHEMA_VERSION,
|
|
137
|
+
handler: "end",
|
|
138
|
+
payload: [payload],
|
|
139
|
+
patches: [],
|
|
140
|
+
};
|
|
141
|
+
await self.store.commitEvent(streamId, currentSeq, serialize(envelope));
|
|
129
142
|
}
|
|
130
143
|
const mailboxTask = self.mailbox.enqueue(async () => {
|
|
131
144
|
await self.ensureActive();
|
|
132
145
|
const stream = self.kernel.startStream(handlerName, args, self.buildContext());
|
|
146
|
+
let finalReturn;
|
|
133
147
|
try {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
148
|
+
while (true) {
|
|
149
|
+
const result = await stream.generator.next();
|
|
150
|
+
if (result.done) {
|
|
151
|
+
finalReturn = result.value;
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
await commitStreamChunk(result.value);
|
|
155
|
+
push({ type: "value", value: result.value });
|
|
139
156
|
}
|
|
140
|
-
|
|
157
|
+
producerDone = true;
|
|
158
|
+
push({ type: "done", returnValue: finalReturn });
|
|
159
|
+
await commitStreamEnd({ state: "complete", returnValue: finalReturn });
|
|
141
160
|
}
|
|
142
161
|
catch (e) {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
}
|
|
162
|
+
stream.discard();
|
|
163
|
+
producerDone = true;
|
|
164
|
+
const errorMsg = e instanceof Error ? e.message : String(e);
|
|
165
|
+
await commitStreamEnd({ state: "error", error: errorMsg });
|
|
166
|
+
push({ type: "error", error: e });
|
|
167
|
+
return;
|
|
148
168
|
}
|
|
149
169
|
const { patches, nextState } = stream.finalize();
|
|
150
170
|
if (patches.length > 0) {
|
|
151
|
-
await self.commit(handlerName, args,
|
|
171
|
+
await self.commit(handlerName, args, finalReturn, patches, nextState);
|
|
152
172
|
}
|
|
153
173
|
});
|
|
154
174
|
async function* outerGenerator() {
|
|
155
175
|
try {
|
|
156
176
|
while (true) {
|
|
157
177
|
const item = await pull();
|
|
158
|
-
if (item.type === "done")
|
|
178
|
+
if (item.type === "done") {
|
|
179
|
+
isLive = false;
|
|
159
180
|
return;
|
|
160
|
-
|
|
181
|
+
}
|
|
182
|
+
if (item.type === "error") {
|
|
183
|
+
isLive = false;
|
|
161
184
|
throw item.error;
|
|
185
|
+
}
|
|
162
186
|
yield item.value;
|
|
163
|
-
signalProducerContinue();
|
|
164
187
|
}
|
|
165
188
|
}
|
|
166
189
|
finally {
|
|
167
|
-
|
|
168
|
-
|
|
190
|
+
isLive = false;
|
|
191
|
+
if (!producerDone) {
|
|
192
|
+
await mailboxTask;
|
|
193
|
+
}
|
|
169
194
|
}
|
|
170
195
|
}
|
|
171
|
-
|
|
196
|
+
const streamRun = {
|
|
197
|
+
id: streamId,
|
|
198
|
+
get seq() {
|
|
199
|
+
return currentSeq;
|
|
200
|
+
},
|
|
201
|
+
get isLive() {
|
|
202
|
+
return isLive;
|
|
203
|
+
},
|
|
204
|
+
[Symbol.asyncIterator]() {
|
|
205
|
+
return outerGenerator();
|
|
206
|
+
},
|
|
207
|
+
};
|
|
208
|
+
return streamRun;
|
|
172
209
|
};
|
|
173
210
|
inspect = async () => {
|
|
174
211
|
await this.ensureActive();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/stream/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,sBAAsB,EAAG,YAAqB,CAAC;AAC5D,eAAO,MAAM,qBAAqB,EAAG,CAAU,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { STREAM_ENTITY_DEF_NAME, STREAM_SCHEMA_VERSION } from "./constants";
|
|
2
|
+
export { readStream, streamStatus } from "./reader";
|
|
3
|
+
export type { ReadStreamOptions, StreamChunk, StreamReader, StreamRun, StreamStatus, } from "./types";
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/stream/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACpD,YAAY,EACV,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,SAAS,EACT,YAAY,GACb,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { PersistenceAdapter } from "../persistence/types";
|
|
2
|
+
import type { ReadStreamOptions, StreamReader, StreamStatus } from "./types";
|
|
3
|
+
export declare function streamStatus(store: PersistenceAdapter, streamId: string): Promise<StreamStatus | null>;
|
|
4
|
+
export declare function readStream<T>(store: PersistenceAdapter, streamId: string, options?: ReadStreamOptions): StreamReader<T>;
|
|
5
|
+
//# sourceMappingURL=reader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reader.d.ts","sourceRoot":"","sources":["../../src/stream/reader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG/D,OAAO,KAAK,EACV,iBAAiB,EAGjB,YAAY,EACZ,YAAY,EACb,MAAM,SAAS,CAAC;AAEjB,wBAAsB,YAAY,CAChC,KAAK,EAAE,kBAAkB,EACzB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAoC9B;AAED,wBAAgB,UAAU,CAAC,CAAC,EAC1B,KAAK,EAAE,kBAAkB,EACzB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,YAAY,CAAC,CAAC,CAAC,CAwCjB"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { deserialize } from "../serde";
|
|
2
|
+
import { STREAM_ENTITY_DEF_NAME } from "./constants";
|
|
3
|
+
export async function streamStatus(store, streamId) {
|
|
4
|
+
const events = await store.getEvents(streamId, 0n);
|
|
5
|
+
if (events.length === 0) {
|
|
6
|
+
return null;
|
|
7
|
+
}
|
|
8
|
+
const lastEvent = events[events.length - 1];
|
|
9
|
+
if (!lastEvent)
|
|
10
|
+
return null;
|
|
11
|
+
const envelope = deserialize(lastEvent.data);
|
|
12
|
+
if (envelope.entityDefName !== STREAM_ENTITY_DEF_NAME) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
if (envelope.handler === "end") {
|
|
16
|
+
const endPayload = envelope.payload[0];
|
|
17
|
+
if (endPayload.state === "error") {
|
|
18
|
+
return {
|
|
19
|
+
state: "error",
|
|
20
|
+
seq: BigInt(events.length - 1),
|
|
21
|
+
error: endPayload.error,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
state: "complete",
|
|
26
|
+
seq: BigInt(events.length - 1),
|
|
27
|
+
returnValue: endPayload.returnValue,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
state: "running",
|
|
32
|
+
seq: BigInt(events.length),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export function readStream(store, streamId, options) {
|
|
36
|
+
const afterSeq = options?.after ?? 0n;
|
|
37
|
+
let isLive = true;
|
|
38
|
+
const reader = {
|
|
39
|
+
get isLive() {
|
|
40
|
+
return isLive;
|
|
41
|
+
},
|
|
42
|
+
async *[Symbol.asyncIterator]() {
|
|
43
|
+
const events = await store.getEvents(streamId, afterSeq);
|
|
44
|
+
for (const event of events) {
|
|
45
|
+
const envelope = deserialize(event.data);
|
|
46
|
+
if (envelope.entityDefName !== STREAM_ENTITY_DEF_NAME) {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (envelope.handler === "end") {
|
|
50
|
+
isLive = false;
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (envelope.handler === "chunk") {
|
|
54
|
+
yield {
|
|
55
|
+
seq: event.version,
|
|
56
|
+
data: envelope.payload[0],
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const status = await streamStatus(store, streamId);
|
|
61
|
+
if (status && status.state !== "running") {
|
|
62
|
+
isLive = false;
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
return reader;
|
|
67
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export interface StreamChunk<T> {
|
|
2
|
+
seq: bigint;
|
|
3
|
+
data: T;
|
|
4
|
+
}
|
|
5
|
+
export interface StreamStatus {
|
|
6
|
+
state: "running" | "complete" | "error";
|
|
7
|
+
seq: bigint;
|
|
8
|
+
error?: string;
|
|
9
|
+
returnValue?: unknown;
|
|
10
|
+
}
|
|
11
|
+
export interface StreamRun<T> extends AsyncIterable<T> {
|
|
12
|
+
readonly id: string;
|
|
13
|
+
readonly seq: bigint;
|
|
14
|
+
readonly isLive: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface StreamReader<T> extends AsyncIterable<StreamChunk<T>> {
|
|
17
|
+
readonly isLive: boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface ReadStreamOptions {
|
|
20
|
+
after?: bigint;
|
|
21
|
+
}
|
|
22
|
+
export interface StreamChunkEnvelope {
|
|
23
|
+
entityDefName: "__stream__";
|
|
24
|
+
schemaVersion: 1;
|
|
25
|
+
handler: "chunk";
|
|
26
|
+
payload: [unknown];
|
|
27
|
+
patches: readonly [];
|
|
28
|
+
}
|
|
29
|
+
export type StreamEndPayload = {
|
|
30
|
+
state: "complete";
|
|
31
|
+
returnValue?: unknown;
|
|
32
|
+
} | {
|
|
33
|
+
state: "error";
|
|
34
|
+
error: string;
|
|
35
|
+
};
|
|
36
|
+
export interface StreamEndEnvelope {
|
|
37
|
+
entityDefName: "__stream__";
|
|
38
|
+
schemaVersion: 1;
|
|
39
|
+
handler: "end";
|
|
40
|
+
payload: [StreamEndPayload];
|
|
41
|
+
patches: readonly [];
|
|
42
|
+
}
|
|
43
|
+
export type StreamEventEnvelope = StreamChunkEnvelope | StreamEndEnvelope;
|
|
44
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/stream/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,CAAC,CAAC;CACT;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC;IACxC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,SAAS,CAAC,CAAC,CAAE,SAAQ,aAAa,CAAC,CAAC,CAAC;IACpD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY,CAAC,CAAC,CAAE,SAAQ,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IACpE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,YAAY,CAAC;IAC5B,aAAa,EAAE,CAAC,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC;IACnB,OAAO,EAAE,SAAS,EAAE,CAAC;CACtB;AAED,MAAM,MAAM,gBAAgB,GACxB;IAAE,KAAK,EAAE,UAAU,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,GAC5C;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtC,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,YAAY,CAAC;IAC5B,aAAa,EAAE,CAAC,CAAC;IACjB,OAAO,EAAE,KAAK,CAAC;IACf,OAAO,EAAE,CAAC,gBAAgB,CAAC,CAAC;IAC5B,OAAO,EAAE,SAAS,EAAE,CAAC;CACtB;AAED,MAAM,MAAM,mBAAmB,GAAG,mBAAmB,GAAG,iBAAiB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/types/public.d.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import type { Draft as ImmerDraft, Patch as ImmerPatch } from "immer";
|
|
2
2
|
import type { PersistenceAdapter } from "../persistence/types";
|
|
3
|
+
import type { ReadStreamOptions as _ReadStreamOptions, StreamChunk as _StreamChunk, StreamReader as _StreamReader, StreamRun as _StreamRun, StreamStatus as _StreamStatus } from "../stream/types";
|
|
3
4
|
import type { _handlers, _initialStateFn, _messages, _name, _persistence, _state, _tag, _upcasters, _versions } from "./internal";
|
|
5
|
+
export type ReadStreamOptions = _ReadStreamOptions;
|
|
6
|
+
export type StreamChunk<T> = _StreamChunk<T>;
|
|
7
|
+
export type StreamReader<T> = _StreamReader<T>;
|
|
8
|
+
export type StreamRun<T> = _StreamRun<T>;
|
|
9
|
+
export type StreamStatus = _StreamStatus;
|
|
4
10
|
export type AnyHandler = (...args: any[]) => any;
|
|
5
11
|
export type Patch = readonly ImmerPatch[];
|
|
6
12
|
export type Draft<T> = ImmerDraft<T>;
|
|
@@ -98,7 +104,7 @@ export type ReadProxy<TDef extends AnyEntityDefinition> = {
|
|
|
98
104
|
export type StreamProxy<TDef extends AnyEntityDefinition> = {
|
|
99
105
|
[K in keyof MessagesOf<TDef> as MessagesOf<TDef>[K] extends {
|
|
100
106
|
verb: "stream";
|
|
101
|
-
} ? K : never]: (...args: MessagesOf<TDef>[K]["payload"]) =>
|
|
107
|
+
} ? K : never]: (...args: MessagesOf<TDef>[K]["payload"]) => StreamRun<MessagesOf<TDef>[K]["progress"]>;
|
|
102
108
|
};
|
|
103
109
|
export type EntityRef<TDef extends AnyEntityDefinition> = {
|
|
104
110
|
readonly read: ReadProxy<TDef>;
|
|
@@ -136,6 +142,8 @@ export interface EntityManagerConfig<TDef extends AnyEntityDefinition> {
|
|
|
136
142
|
}
|
|
137
143
|
export interface EntityManager<TDef extends AnyEntityDefinition> {
|
|
138
144
|
get(id: string): EntityRef<TDef>;
|
|
145
|
+
readStream<T = unknown>(streamId: string, options?: ReadStreamOptions): StreamReader<T>;
|
|
146
|
+
streamStatus(streamId: string): Promise<StreamStatus | null>;
|
|
139
147
|
stop(): Promise<void>;
|
|
140
148
|
}
|
|
141
149
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/types/public.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,IAAI,UAAU,EAAE,KAAK,IAAI,UAAU,EAAE,MAAM,OAAO,CAAC;AACtE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EACV,SAAS,EACT,eAAe,EACf,SAAS,EACT,KAAK,EACL,YAAY,EACZ,MAAM,EACN,IAAI,EACJ,UAAU,EACV,SAAS,EACV,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/types/public.ts"],"names":[],"mappings":"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"}
|