solid-objects 0.14.5 → 0.14.7

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.
Files changed (114) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +4 -0
  3. package/dist/actor-runtime.d.ts +36 -0
  4. package/dist/actor-runtime.d.ts.map +1 -0
  5. package/dist/actor-runtime.js +2 -0
  6. package/dist/actor-runtime.js.map +1 -0
  7. package/dist/application-database.d.ts.map +1 -1
  8. package/dist/application-database.js +2 -2
  9. package/dist/application-database.js.map +1 -1
  10. package/dist/browser/index.js +1 -1
  11. package/dist/browser/index.js.map +1 -1
  12. package/dist/cloudflare/configuration.d.ts +32 -0
  13. package/dist/cloudflare/configuration.d.ts.map +1 -0
  14. package/dist/cloudflare/configuration.js +46 -0
  15. package/dist/cloudflare/configuration.js.map +1 -0
  16. package/dist/cloudflare/engine.d.ts +43 -0
  17. package/dist/cloudflare/engine.d.ts.map +1 -0
  18. package/dist/cloudflare/engine.js +921 -0
  19. package/dist/cloudflare/engine.js.map +1 -0
  20. package/dist/cloudflare/host.d.ts +10 -0
  21. package/dist/cloudflare/host.d.ts.map +1 -0
  22. package/dist/cloudflare/host.js +44 -0
  23. package/dist/cloudflare/host.js.map +1 -0
  24. package/dist/cloudflare/index.d.ts +9 -0
  25. package/dist/cloudflare/index.d.ts.map +1 -0
  26. package/dist/cloudflare/index.js +8 -0
  27. package/dist/cloudflare/index.js.map +1 -0
  28. package/dist/cloudflare/platform.d.ts +2 -0
  29. package/dist/cloudflare/platform.d.ts.map +1 -0
  30. package/dist/cloudflare/platform.js +4 -0
  31. package/dist/cloudflare/platform.js.map +1 -0
  32. package/dist/cloudflare/protocol.d.ts +58 -0
  33. package/dist/cloudflare/protocol.d.ts.map +1 -0
  34. package/dist/cloudflare/protocol.js +77 -0
  35. package/dist/cloudflare/protocol.js.map +1 -0
  36. package/dist/cloudflare/records.d.ts +71 -0
  37. package/dist/cloudflare/records.d.ts.map +1 -0
  38. package/dist/cloudflare/records.js +2 -0
  39. package/dist/cloudflare/records.js.map +1 -0
  40. package/dist/cloudflare/runtime.d.ts +83 -0
  41. package/dist/cloudflare/runtime.d.ts.map +1 -0
  42. package/dist/cloudflare/runtime.js +321 -0
  43. package/dist/cloudflare/runtime.js.map +1 -0
  44. package/dist/cloudflare/session.d.ts +12 -0
  45. package/dist/cloudflare/session.d.ts.map +1 -0
  46. package/dist/cloudflare/session.js +332 -0
  47. package/dist/cloudflare/session.js.map +1 -0
  48. package/dist/cloudflare/storage.d.ts +25 -0
  49. package/dist/cloudflare/storage.d.ts.map +1 -0
  50. package/dist/cloudflare/storage.js +195 -0
  51. package/dist/cloudflare/storage.js.map +1 -0
  52. package/dist/context.d.ts +5 -4
  53. package/dist/context.d.ts.map +1 -1
  54. package/dist/context.js +3 -0
  55. package/dist/context.js.map +1 -1
  56. package/dist/core.d.ts +8 -0
  57. package/dist/core.d.ts.map +1 -0
  58. package/dist/core.js +4 -0
  59. package/dist/core.js.map +1 -0
  60. package/dist/database/mysql.d.ts +2 -2
  61. package/dist/database/mysql.d.ts.map +1 -1
  62. package/dist/database/mysql.js +4 -1
  63. package/dist/database/mysql.js.map +1 -1
  64. package/dist/database/postgresql.d.ts +2 -2
  65. package/dist/database/postgresql.d.ts.map +1 -1
  66. package/dist/database/postgresql.js +4 -2
  67. package/dist/database/postgresql.js.map +1 -1
  68. package/dist/database/types.d.ts +4 -1
  69. package/dist/database/types.d.ts.map +1 -1
  70. package/dist/default-runtime.d.ts +4 -4
  71. package/dist/default-runtime.d.ts.map +1 -1
  72. package/dist/default-runtime.js.map +1 -1
  73. package/dist/doctor.js +2 -2
  74. package/dist/doctor.js.map +1 -1
  75. package/dist/errors.d.ts +14 -0
  76. package/dist/errors.d.ts.map +1 -1
  77. package/dist/errors.js +9 -0
  78. package/dist/errors.js.map +1 -1
  79. package/dist/index.d.ts +1 -1
  80. package/dist/index.d.ts.map +1 -1
  81. package/dist/index.js.map +1 -1
  82. package/dist/realtime.d.ts +18 -2
  83. package/dist/realtime.d.ts.map +1 -1
  84. package/dist/realtime.js.map +1 -1
  85. package/dist/reference.d.ts +5 -5
  86. package/dist/reference.d.ts.map +1 -1
  87. package/dist/reference.js.map +1 -1
  88. package/dist/repository.d.ts +15 -1
  89. package/dist/repository.d.ts.map +1 -1
  90. package/dist/repository.js +303 -65
  91. package/dist/repository.js.map +1 -1
  92. package/dist/runtime.d.ts.map +1 -1
  93. package/dist/runtime.js +18 -53
  94. package/dist/runtime.js.map +1 -1
  95. package/dist/schema.d.ts.map +1 -1
  96. package/dist/schema.js +29 -5
  97. package/dist/schema.js.map +1 -1
  98. package/dist/turn.d.ts +34 -0
  99. package/dist/turn.d.ts.map +1 -0
  100. package/dist/turn.js +57 -0
  101. package/dist/turn.js.map +1 -0
  102. package/dist/version.d.ts +1 -1
  103. package/dist/version.js +1 -1
  104. package/docs/api.md +28 -2
  105. package/docs/architecture.md +5 -3
  106. package/docs/cloudflare.md +155 -0
  107. package/docs/parity.md +28 -9
  108. package/docs/support.md +12 -11
  109. package/examples/cloudflare/README.md +49 -0
  110. package/examples/cloudflare/environment.d.ts +14 -0
  111. package/examples/cloudflare/shopping-cart.ts +65 -0
  112. package/examples/cloudflare/worker.ts +87 -0
  113. package/examples/cloudflare/wrangler.jsonc +15 -0
  114. package/package.json +20 -5
@@ -0,0 +1,332 @@
1
+ import { DurableObject } from "cloudflare:workers";
2
+ import { Unauthorized } from "../errors.js";
3
+ import { parseSubscriptionRequest } from "../realtime.js";
4
+ import { jsonObject, normalizeJson, utf8ByteLength } from "../serialization.js";
5
+ import { actorName, callHost, } from "./protocol.js";
6
+ export function createDurableObjectsSessionHost(options) {
7
+ const maximum = options.maxSubscriptions ?? 100;
8
+ if (!Number.isSafeInteger(maximum) || maximum <= 0)
9
+ throw new TypeError("maxSubscriptions must be a positive safe integer");
10
+ return class SolidObjectsSessionHost extends DurableObject {
11
+ #receiving = Promise.resolve();
12
+ constructor(context, environment) {
13
+ super(context, environment);
14
+ this.ctx.storage.transactionSync(() => {
15
+ this.ctx.storage.sql.exec(`
16
+ CREATE TABLE IF NOT EXISTS subscriptions (identity TEXT PRIMARY KEY, id TEXT NOT NULL UNIQUE, record TEXT NOT NULL);
17
+ CREATE TABLE IF NOT EXISTS revisions (subscription_id TEXT NOT NULL, channel TEXT NOT NULL, incarnation TEXT NOT NULL, revision TEXT NOT NULL, PRIMARY KEY(subscription_id, channel));
18
+ `);
19
+ });
20
+ }
21
+ async fetch(request) {
22
+ try {
23
+ if (request.headers.get("Upgrade") !== "websocket")
24
+ return new Response("WebSocket required", { status: 426 });
25
+ return await this.#open({
26
+ sessionName: request.headers.get("X-Solid-Session-Name") ?? "",
27
+ sessionId: request.headers.get("X-Solid-Session-Id") ?? "",
28
+ expiresAt: Number(request.headers.get("X-Solid-Session-Expiry")),
29
+ });
30
+ }
31
+ catch {
32
+ return new Response("Unauthorized", { status: 401 });
33
+ }
34
+ }
35
+ async #open(input) {
36
+ if (this.#session())
37
+ throw new Unauthorized("session connection already exists");
38
+ if (!input.sessionId ||
39
+ utf8ByteLength(input.sessionId) > 1_024 ||
40
+ !Number.isFinite(input.expiresAt) ||
41
+ input.expiresAt <= Date.now())
42
+ throw new Unauthorized("invalid session");
43
+ const authorization = await options.resolveAuthorizationContext({
44
+ sessionId: input.sessionId,
45
+ environment: this.env,
46
+ });
47
+ if (authorization === null || input.expiresAt <= Date.now())
48
+ throw new Unauthorized("session is not authorized");
49
+ await this.#atomic(() => {
50
+ if (this.#session())
51
+ throw new Unauthorized("session connection already exists");
52
+ this.ctx.storage.kv.put("session", { ...input, closed: false });
53
+ });
54
+ const pair = new WebSocketPair();
55
+ this.ctx.acceptWebSocket(pair[1]);
56
+ pair[1].serializeAttachment({ sessionName: input.sessionName });
57
+ return new Response(null, { status: 101, webSocket: pair[0] });
58
+ }
59
+ async webSocketMessage(socket, value) {
60
+ const receive = this.#receiving.then(async () => {
61
+ if (typeof value !== "string" || utf8ByteLength(value) > 16_384)
62
+ throw new TypeError("invalid subscription frame");
63
+ const request = parseSubscriptionRequest(JSON.parse(value));
64
+ const session = this.#session();
65
+ if (!session || session.closed || session.expiresAt <= Date.now())
66
+ throw new Unauthorized("session expired");
67
+ const identity = actorName(request);
68
+ const previous = this.#subscription(identity);
69
+ if (request.action === "unsubscribe") {
70
+ if (!previous)
71
+ return;
72
+ previous.status = "removing";
73
+ previous.retryAt = Date.now();
74
+ await this.#atomic(() => this.#save(previous));
75
+ await this.#synchronize(previous);
76
+ return;
77
+ }
78
+ if (!previous && this.#subscriptions().length >= maximum)
79
+ throw new TypeError("subscription limit exceeded");
80
+ const subscription = {
81
+ actorType: request.actorType,
82
+ actorId: request.actorId,
83
+ id: previous?.id ?? crypto.randomUUID(),
84
+ payloads: [...(request.payloads ?? [])],
85
+ status: "registering",
86
+ retryAt: Date.now(),
87
+ incarnationOrder: previous?.incarnationOrder ?? "0",
88
+ };
89
+ await this.#atomic(() => {
90
+ this.#save(subscription);
91
+ this.ctx.storage.sql.exec("DELETE FROM revisions WHERE subscription_id = ?", subscription.id);
92
+ });
93
+ await this.#synchronize(subscription);
94
+ });
95
+ this.#receiving = receive.catch(() => undefined);
96
+ try {
97
+ await receive;
98
+ }
99
+ catch {
100
+ socket.close(1008, "subscription unavailable");
101
+ await this.#close();
102
+ }
103
+ }
104
+ async publish(input) {
105
+ const subscription = this.#subscriptions().find((entry) => entry.id === input.subscriptionId);
106
+ if (!subscription || subscription.status === "removing")
107
+ return;
108
+ const authorization = await this.#authorization();
109
+ if (authorization === null) {
110
+ await this.#close();
111
+ return;
112
+ }
113
+ let projected;
114
+ try {
115
+ projected = jsonObject(await callHost({
116
+ backend: options.backend(this.env),
117
+ request: {
118
+ ...subscription,
119
+ method: "projection",
120
+ authorizationContext: authorization,
121
+ payload: { payloads: subscription.payloads },
122
+ },
123
+ }));
124
+ }
125
+ catch (error) {
126
+ if (!(error instanceof Unauthorized))
127
+ throw error;
128
+ subscription.status = "removing";
129
+ await this.#atomic(() => this.#save(subscription));
130
+ await this.#synchronize(subscription);
131
+ return;
132
+ }
133
+ const current = jsonObject(projected.event);
134
+ if (current.instanceId !== input.event.instanceId)
135
+ return;
136
+ this.#send(subscription, {
137
+ envelope: input.event,
138
+ incarnationOrder: String(projected.incarnationOrder),
139
+ });
140
+ for (const payload of payloadArray(projected.payloads))
141
+ this.#send(subscription, {
142
+ envelope: payload,
143
+ incarnationOrder: String(projected.incarnationOrder),
144
+ });
145
+ }
146
+ async webSocketClose(socket) {
147
+ socket.close(1000, "closed");
148
+ await this.#close();
149
+ }
150
+ async webSocketError(socket) {
151
+ socket.close(1011, "connection failed");
152
+ await this.#close();
153
+ }
154
+ async alarm() {
155
+ const session = this.#session();
156
+ if (session && session.expiresAt <= Date.now()) {
157
+ for (const socket of this.ctx.getWebSockets())
158
+ socket.close(1008, "session expired");
159
+ await this.#close();
160
+ }
161
+ for (const subscription of this.#subscriptions()) {
162
+ if (subscription.status === "active" || subscription.retryAt > Date.now())
163
+ continue;
164
+ try {
165
+ await this.#synchronize(subscription);
166
+ }
167
+ catch {
168
+ await this.#defer(subscription);
169
+ }
170
+ }
171
+ await this.#atomic(() => undefined);
172
+ }
173
+ #session() {
174
+ return this.ctx.storage.kv.get("session");
175
+ }
176
+ #subscriptions() {
177
+ return this.ctx.storage.sql
178
+ .exec("SELECT record FROM subscriptions")
179
+ .toArray()
180
+ .map((row) => JSON.parse(row.record));
181
+ }
182
+ #subscription(identity) {
183
+ const row = this.ctx.storage.sql
184
+ .exec("SELECT record FROM subscriptions WHERE identity = ?", identity)
185
+ .toArray()[0];
186
+ return row ? JSON.parse(row.record) : undefined;
187
+ }
188
+ #save(subscription) {
189
+ this.ctx.storage.sql.exec("INSERT INTO subscriptions(identity, id, record) VALUES (?, ?, ?) ON CONFLICT(identity) DO UPDATE SET id = excluded.id, record = excluded.record", actorName(subscription), subscription.id, JSON.stringify(subscription));
190
+ }
191
+ async #authorization() {
192
+ const session = this.#session();
193
+ if (!session || session.closed || session.expiresAt <= Date.now())
194
+ return null;
195
+ const value = await options.resolveAuthorizationContext({
196
+ sessionId: session.sessionId,
197
+ environment: this.env,
198
+ });
199
+ return value === null ? null : normalizeJson(value);
200
+ }
201
+ async #synchronize(subscription) {
202
+ const session = this.#session();
203
+ if (!session)
204
+ return;
205
+ const authorization = subscription.status === "removing" ? null : await this.#authorization();
206
+ if (authorization === null) {
207
+ subscription.status = "removing";
208
+ await this.#atomic(() => {
209
+ const current = this.#subscription(actorName(subscription));
210
+ if (current?.id === subscription.id)
211
+ this.#save({ ...current, status: "removing" });
212
+ });
213
+ }
214
+ await this.#defer(subscription);
215
+ const projected = await callHost({
216
+ backend: options.backend(this.env),
217
+ request: {
218
+ ...subscription,
219
+ method: subscription.status === "removing" ? "unsubscribe" : "subscribe",
220
+ authorizationContext: authorization,
221
+ payload: {
222
+ subscriptionId: subscription.id,
223
+ sessionName: session.sessionName,
224
+ expiresAt: session.expiresAt,
225
+ payloads: subscription.payloads,
226
+ },
227
+ },
228
+ });
229
+ await this.#atomic(() => {
230
+ const current = this.#subscription(actorName(subscription));
231
+ if (!current || current.id !== subscription.id)
232
+ return;
233
+ if (subscription.status === "removing") {
234
+ this.ctx.storage.sql.exec("DELETE FROM subscriptions WHERE id = ?", subscription.id);
235
+ this.ctx.storage.sql.exec("DELETE FROM revisions WHERE subscription_id = ?", subscription.id);
236
+ return;
237
+ }
238
+ if (current.status === "removing" || this.#session()?.closed)
239
+ return;
240
+ subscription.status = "active";
241
+ this.#save({ ...current, status: "active" });
242
+ });
243
+ if (subscription.status !== "active" || projected === null)
244
+ return;
245
+ const projection = jsonObject(projected);
246
+ this.#send(subscription, {
247
+ envelope: jsonObject(projection.event),
248
+ incarnationOrder: String(projection.incarnationOrder),
249
+ });
250
+ for (const payload of payloadArray(projection.payloads))
251
+ this.#send(subscription, {
252
+ envelope: payload,
253
+ incarnationOrder: String(projection.incarnationOrder),
254
+ });
255
+ }
256
+ async #defer(subscription) {
257
+ subscription.retryAt = Date.now() + 30_000;
258
+ await this.#atomic(() => {
259
+ const current = this.#subscription(actorName(subscription));
260
+ if (!current || current.id !== subscription.id)
261
+ return;
262
+ this.#save({ ...current, retryAt: subscription.retryAt });
263
+ });
264
+ }
265
+ #send(subscription, delivery) {
266
+ const { envelope, incarnationOrder } = delivery;
267
+ const session = this.#session();
268
+ const current = this.#subscription(actorName(subscription));
269
+ if (!session ||
270
+ session.closed ||
271
+ session.expiresAt <= Date.now() ||
272
+ !current ||
273
+ current.id !== subscription.id ||
274
+ current.status === "removing")
275
+ return;
276
+ const channel = envelope.kind === "payload" ? `payload:${String(envelope.name)}` : "invalidation";
277
+ const incarnation = String(envelope.instanceId);
278
+ const revision = String(envelope.revision);
279
+ this.ctx.storage.transactionSync(() => {
280
+ if (BigInt(incarnationOrder) < BigInt(current.incarnationOrder))
281
+ return;
282
+ if (BigInt(incarnationOrder) > BigInt(current.incarnationOrder)) {
283
+ this.ctx.storage.sql.exec("DELETE FROM revisions WHERE subscription_id = ?", subscription.id);
284
+ this.#save({ ...current, incarnationOrder });
285
+ }
286
+ const previous = this.ctx.storage.sql
287
+ .exec("SELECT incarnation, revision FROM revisions WHERE subscription_id = ? AND channel = ?", subscription.id, channel)
288
+ .toArray()[0];
289
+ if (previous?.incarnation === incarnation && BigInt(previous.revision) >= BigInt(revision))
290
+ return;
291
+ this.ctx.storage.sql.exec("INSERT INTO revisions(subscription_id, channel, incarnation, revision) VALUES (?, ?, ?, ?) ON CONFLICT(subscription_id, channel) DO UPDATE SET incarnation = excluded.incarnation, revision = excluded.revision", subscription.id, channel, incarnation, revision);
292
+ for (const socket of this.ctx.getWebSockets())
293
+ socket.send(JSON.stringify(envelope));
294
+ });
295
+ }
296
+ async #close() {
297
+ await this.#atomic(() => {
298
+ const session = this.#session();
299
+ if (session)
300
+ this.ctx.storage.kv.put("session", { ...session, closed: true });
301
+ for (const subscription of this.#subscriptions())
302
+ this.#save({ ...subscription, status: "removing", retryAt: Date.now() });
303
+ });
304
+ for (const socket of this.ctx.getWebSockets()) {
305
+ if (socket.readyState < WebSocket.CLOSING)
306
+ socket.close(1008, "session closed");
307
+ }
308
+ }
309
+ async #atomic(callback) {
310
+ await this.ctx.storage.transaction(async () => {
311
+ callback();
312
+ const session = this.#session();
313
+ const due = this.#subscriptions()
314
+ .filter((subscription) => subscription.status !== "active")
315
+ .map((subscription) => subscription.retryAt);
316
+ if (session && !session.closed)
317
+ due.push(session.expiresAt);
318
+ if (due.length === 0) {
319
+ await this.ctx.storage.deleteAlarm();
320
+ return;
321
+ }
322
+ await this.ctx.storage.setAlarm(Math.max(Date.now() + 1, Math.min(...due)));
323
+ });
324
+ }
325
+ };
326
+ }
327
+ function payloadArray(value) {
328
+ if (!Array.isArray(value))
329
+ throw new TypeError("invalid projection payloads");
330
+ return value.map((payload) => jsonObject(payload));
331
+ }
332
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/cloudflare/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { Instance, Message, Outbox, Reminder, Subscription } from "./records.js";
2
+ import type { CloudflareSettings } from "./configuration.js";
3
+ type EncodableValue = object | string | number | boolean | null;
4
+ export declare class ActorStorage {
5
+ readonly storage: DurableObjectStorage;
6
+ readonly settings: CloudflareSettings;
7
+ constructor(storage: DurableObjectStorage, settings: CloudflareSettings);
8
+ instance(): Instance | undefined;
9
+ metadata<Value>(key: string): Value | undefined;
10
+ saveMetadata(key: string, value: EncodableValue): void;
11
+ saveInstance(instance: Instance): void;
12
+ rows<Row>(query: string, parameters?: readonly (string | number | null)[]): Row[];
13
+ message(id: string): Message | undefined;
14
+ saveMessage(message: Message): void;
15
+ head(): Message | undefined;
16
+ saveOutbox(outbox: Outbox): void;
17
+ outboxHeads(): Outbox[];
18
+ saveReminder(reminder: Reminder): void;
19
+ saveSubscription(subscription: Subscription): void;
20
+ atomic<Result>(callback: () => Result): Promise<Result>;
21
+ schedule(): Promise<void>;
22
+ prune(): void;
23
+ }
24
+ export {};
25
+ //# sourceMappingURL=storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/cloudflare/storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AACrF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAG5D,KAAK,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAA;AAE/D,qBAAa,YAAY;IAErB,QAAQ,CAAC,OAAO,EAAE,oBAAoB;IACtC,QAAQ,CAAC,QAAQ,EAAE,kBAAkB;gBAD5B,OAAO,EAAE,oBAAoB,EAC7B,QAAQ,EAAE,kBAAkB;IAyDvC,QAAQ,IAAI,QAAQ,GAAG,SAAS;IAIhC,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS;IAO/C,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,IAAI;IAQtD,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAItC,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,GAAE,SAAS,CAAC,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC,EAAO,GAAG,GAAG,EAAE;IAOrF,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAIxC,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAuBnC,IAAI,IAAI,OAAO,GAAG,SAAS;IAS3B,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAyBhC,WAAW,IAAI,MAAM,EAAE;IAWvB,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAUtC,gBAAgB,CAAC,YAAY,EAAE,YAAY,GAAG,IAAI;IAS5C,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQvD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IA2C/B,KAAK,IAAI,IAAI;CA2Bd"}
@@ -0,0 +1,195 @@
1
+ import { PayloadTooLarge } from "../errors.js";
2
+ import { utf8ByteLength } from "../serialization.js";
3
+ export class ActorStorage {
4
+ storage;
5
+ settings;
6
+ constructor(storage, settings) {
7
+ this.storage = storage;
8
+ this.settings = settings;
9
+ storage.transactionSync(() => {
10
+ storage.sql.exec(`
11
+ CREATE TABLE IF NOT EXISTS schema_migrations (version INTEGER PRIMARY KEY);
12
+ CREATE TABLE IF NOT EXISTS metadata (key TEXT PRIMARY KEY, value TEXT NOT NULL);
13
+ CREATE TABLE IF NOT EXISTS messages (
14
+ id TEXT PRIMARY KEY, request_id TEXT NOT NULL UNIQUE, incarnation TEXT NOT NULL,
15
+ sequence INTEGER NOT NULL, idempotency_key TEXT, status TEXT NOT NULL,
16
+ available_at INTEGER NOT NULL, completed_at INTEGER, record TEXT NOT NULL
17
+ );
18
+ CREATE UNIQUE INDEX IF NOT EXISTS message_idempotency ON messages(incarnation, idempotency_key) WHERE idempotency_key IS NOT NULL;
19
+ CREATE INDEX IF NOT EXISTS mailbox ON messages(incarnation, status, sequence);
20
+ CREATE INDEX IF NOT EXISTS message_retention ON messages(completed_at);
21
+ CREATE TABLE IF NOT EXISTS receipts (request_id TEXT PRIMARY KEY, message_id TEXT NOT NULL);
22
+ CREATE INDEX IF NOT EXISTS receipt_message ON receipts(message_id);
23
+ CREATE TABLE IF NOT EXISTS outboxes (
24
+ id TEXT PRIMARY KEY, incarnation TEXT NOT NULL, message_id TEXT NOT NULL, kind TEXT NOT NULL,
25
+ destination TEXT NOT NULL, sequence INTEGER NOT NULL, status TEXT NOT NULL,
26
+ available_at INTEGER NOT NULL, completed_at INTEGER, record TEXT NOT NULL
27
+ );
28
+ CREATE INDEX IF NOT EXISTS outbox_delivery ON outboxes(kind, destination, status, sequence);
29
+ CREATE INDEX IF NOT EXISTS outbox_retention ON outboxes(completed_at);
30
+ CREATE INDEX IF NOT EXISTS outbox_source ON outboxes(message_id);
31
+ CREATE TABLE IF NOT EXISTS reminders (name TEXT PRIMARY KEY, status TEXT NOT NULL, due_at INTEGER NOT NULL, record TEXT NOT NULL);
32
+ CREATE INDEX IF NOT EXISTS reminder_due ON reminders(status, due_at);
33
+ CREATE TABLE IF NOT EXISTS subscriptions (id TEXT PRIMARY KEY, expires_at INTEGER NOT NULL, record TEXT NOT NULL);
34
+ CREATE INDEX IF NOT EXISTS subscription_expiry ON subscriptions(expires_at);
35
+ INSERT OR IGNORE INTO schema_migrations(version) VALUES (1);
36
+ `);
37
+ const version = storage.sql
38
+ .exec("SELECT MAX(version) AS version FROM schema_migrations")
39
+ .one().version;
40
+ if (version !== 1)
41
+ throw new Error("unsupported Durable Objects storage schema");
42
+ const instance = this.instance();
43
+ if (instance) {
44
+ instance.generation = String(BigInt(instance.generation) + 1n);
45
+ this.saveInstance(instance);
46
+ }
47
+ for (const message of this.rows("SELECT record FROM messages WHERE status = 'claimed'")) {
48
+ message.status = "ready";
49
+ message.availableAt = Date.now();
50
+ message.generation = null;
51
+ this.saveMessage(message);
52
+ }
53
+ for (const outbox of this.rows("SELECT record FROM outboxes WHERE status = 'claimed'")) {
54
+ outbox.status = "pending";
55
+ outbox.availableAt = Date.now();
56
+ this.saveOutbox(outbox);
57
+ }
58
+ });
59
+ }
60
+ instance() {
61
+ return this.metadata("instance");
62
+ }
63
+ metadata(key) {
64
+ const row = this.storage.sql
65
+ .exec("SELECT value FROM metadata WHERE key = ?", key)
66
+ .toArray()[0];
67
+ return row ? JSON.parse(row.value) : undefined;
68
+ }
69
+ saveMetadata(key, value) {
70
+ this.storage.sql.exec("INSERT INTO metadata(key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value", key, encodedRecord(value, [key]));
71
+ }
72
+ saveInstance(instance) {
73
+ this.saveMetadata("instance", instance);
74
+ }
75
+ rows(query, parameters = []) {
76
+ return this.storage.sql
77
+ .exec(query, ...parameters)
78
+ .toArray()
79
+ .map((row) => JSON.parse(row.record));
80
+ }
81
+ message(id) {
82
+ return this.rows("SELECT record FROM messages WHERE id = ?", [id])[0];
83
+ }
84
+ saveMessage(message) {
85
+ this.storage.sql.exec(`INSERT INTO messages(id, request_id, incarnation, sequence, idempotency_key, status, available_at, completed_at, record)
86
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(id) DO UPDATE SET status = excluded.status,
87
+ available_at = excluded.available_at, completed_at = excluded.completed_at, record = excluded.record`, message.id, message.requestId, message.incarnation, message.sequence, message.idempotencyKey, message.status, message.availableAt, message.completedAt, encodedRecord(message, [
88
+ message.id,
89
+ message.requestId,
90
+ message.incarnation,
91
+ message.idempotencyKey ?? "",
92
+ message.status,
93
+ ]));
94
+ }
95
+ head() {
96
+ const instance = this.instance();
97
+ if (!instance || instance.paused)
98
+ return undefined;
99
+ return this.rows("SELECT record FROM messages WHERE incarnation = ? AND status IN ('ready', 'claimed') ORDER BY sequence LIMIT 1", [instance.incarnation])[0];
100
+ }
101
+ saveOutbox(outbox) {
102
+ this.storage.sql.exec(`INSERT INTO outboxes(id, incarnation, message_id, kind, destination, sequence, status, available_at, completed_at, record)
103
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(id) DO UPDATE SET status = excluded.status,
104
+ available_at = excluded.available_at, completed_at = excluded.completed_at, record = excluded.record`, outbox.id, outbox.incarnation, outbox.messageId, outbox.kind, outbox.destination, outbox.sequence, outbox.status, outbox.availableAt, outbox.completedAt, encodedRecord(outbox, [
105
+ outbox.id,
106
+ outbox.incarnation,
107
+ outbox.messageId,
108
+ outbox.kind,
109
+ outbox.destination,
110
+ outbox.status,
111
+ ]));
112
+ }
113
+ outboxHeads() {
114
+ return this.rows(`SELECT current.record FROM outboxes current WHERE current.status IN ('pending', 'claimed')
115
+ AND NOT EXISTS (SELECT 1 FROM outboxes earlier WHERE earlier.kind = current.kind
116
+ AND earlier.destination = current.destination AND earlier.status IN ('pending', 'claimed', 'dead')
117
+ AND (earlier.sequence < current.sequence OR (earlier.sequence = current.sequence AND earlier.rowid < current.rowid)))
118
+ ORDER BY current.available_at, current.rowid LIMIT ?`, [this.settings.maxMessagesPerActivationPass]);
119
+ }
120
+ saveReminder(reminder) {
121
+ this.storage.sql.exec("INSERT INTO reminders(name, status, due_at, record) VALUES (?, ?, ?, ?) ON CONFLICT(name) DO UPDATE SET status = excluded.status, due_at = excluded.due_at, record = excluded.record", reminder.name, reminder.status, reminder.at, encodedRecord(reminder, [reminder.name, reminder.status]));
122
+ }
123
+ saveSubscription(subscription) {
124
+ this.storage.sql.exec("INSERT INTO subscriptions(id, expires_at, record) VALUES (?, ?, ?) ON CONFLICT(id) DO UPDATE SET expires_at = excluded.expires_at, record = excluded.record", subscription.id, subscription.expiresAt, encodedRecord(subscription, [subscription.id]));
125
+ }
126
+ async atomic(callback) {
127
+ return this.storage.transaction(async () => {
128
+ const result = callback();
129
+ await this.schedule();
130
+ return result;
131
+ });
132
+ }
133
+ async schedule() {
134
+ const due = [];
135
+ if (this.metadata("receiptCleanupPending"))
136
+ due.push(Date.now());
137
+ const head = this.head();
138
+ if (head)
139
+ due.push(head.availableAt);
140
+ for (const outbox of this.outboxHeads())
141
+ due.push(outbox.availableAt);
142
+ const reminder = this.instance()?.paused
143
+ ? null
144
+ : this.storage.sql
145
+ .exec("SELECT MIN(due_at) AS due FROM reminders WHERE status = 'scheduled'")
146
+ .one().due;
147
+ if (reminder !== null) {
148
+ const count = this.storage.sql
149
+ .exec("SELECT COUNT(*) AS count FROM messages WHERE status IN ('ready', 'claimed')")
150
+ .one().count;
151
+ const availableAt = count >= this.settings.maxMailboxLength
152
+ ? Math.max(Date.now() + 1_000, head?.availableAt ?? Date.now() + 30_000)
153
+ : reminder;
154
+ due.push(availableAt);
155
+ }
156
+ const subscription = this.storage.sql
157
+ .exec("SELECT MIN(expires_at) AS due FROM subscriptions")
158
+ .one().due;
159
+ if (subscription !== null)
160
+ due.push(subscription);
161
+ for (const query of [
162
+ "SELECT MIN(completed_at) AS due FROM outboxes WHERE status = 'completed'",
163
+ "SELECT MIN(completed_at) AS due FROM messages WHERE status IN ('completed', 'rejected') AND NOT EXISTS (SELECT 1 FROM outboxes WHERE outboxes.message_id = messages.id)",
164
+ ]) {
165
+ const retention = this.storage.sql.exec(query).one().due;
166
+ if (retention !== null)
167
+ due.push(retention + this.settings.messageRetentionMilliseconds);
168
+ }
169
+ if (due.length === 0) {
170
+ await this.storage.deleteAlarm();
171
+ return;
172
+ }
173
+ await this.storage.setAlarm(Math.max(Date.now() + 1, Math.min(...due)));
174
+ }
175
+ prune() {
176
+ const before = Date.now() - this.settings.messageRetentionMilliseconds;
177
+ const limit = this.settings.pruneBatchSize;
178
+ this.storage.sql.exec("DELETE FROM subscriptions WHERE id IN (SELECT id FROM subscriptions WHERE expires_at <= ? LIMIT ?)", Date.now(), limit);
179
+ this.storage.sql.exec("DELETE FROM outboxes WHERE id IN (SELECT id FROM outboxes WHERE status = 'completed' AND completed_at <= ? LIMIT ?)", before, limit);
180
+ const removedMessages = this.storage.sql.exec(`DELETE FROM messages WHERE id IN (SELECT id FROM messages WHERE completed_at <= ? AND status IN ('completed', 'rejected')
181
+ AND NOT EXISTS (SELECT 1 FROM outboxes WHERE outboxes.message_id = messages.id) LIMIT ?)`, before, limit);
182
+ if (removedMessages.rowsWritten === 0 && !this.metadata("receiptCleanupPending"))
183
+ return;
184
+ const removedReceipts = this.storage.sql.exec("DELETE FROM receipts WHERE request_id IN (SELECT request_id FROM receipts WHERE NOT EXISTS (SELECT 1 FROM messages WHERE messages.id = receipts.message_id) LIMIT ?)", limit);
185
+ this.saveMetadata("receiptCleanupPending", removedReceipts.rowsWritten >= limit);
186
+ }
187
+ }
188
+ function encodedRecord(value, indexedValues) {
189
+ const encoded = JSON.stringify(value);
190
+ const size = indexedValues.reduce((total, value) => total + utf8ByteLength(value), utf8ByteLength(encoded));
191
+ if (size > 1_999_000)
192
+ throw new PayloadTooLarge("Durable Objects storage record exceeds the SQLite row limit");
193
+ return encoded;
194
+ }
195
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/cloudflare/storage.ts"],"names":[],"mappings":"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"}
package/dist/context.d.ts CHANGED
@@ -1,20 +1,21 @@
1
1
  import type { Actor } from "./actor.js";
2
- import type { SolidObjectsRuntime } from "./runtime.js";
2
+ import type { ActorRuntime } from "./actor-runtime.js";
3
3
  import type { MessageContext } from "./types.js";
4
4
  interface ActorExecutionContext {
5
5
  actor: Actor;
6
- runtime: SolidObjectsRuntime;
6
+ runtime: ActorRuntime;
7
7
  message?: MessageContext;
8
8
  }
9
9
  export declare function currentActor(): Actor | undefined;
10
- export declare function currentRuntime(): SolidObjectsRuntime | undefined;
10
+ export declare function currentRuntime(): ActorRuntime | undefined;
11
11
  export declare function currentMessage(): MessageContext | undefined;
12
12
  export declare function applicationWritesForbidden(): boolean;
13
13
  export declare function withActorContext<Result>(context: ActorExecutionContext, callback: () => Result): Result;
14
14
  export declare function withActorProjection<Result>(context: {
15
15
  actor: Actor;
16
- runtime: SolidObjectsRuntime;
16
+ runtime: ActorRuntime;
17
17
  }, callback: () => Result): Result;
18
18
  export declare function withApplicationWritesForbidden<Result>(callback: () => Result): Result;
19
+ export declare function withRuntime<Result>(runtime: ActorRuntime, callback: () => Result): Result;
19
20
  export {};
20
21
  //# sourceMappingURL=context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AACvC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAShD,UAAU,qBAAqB;IAC7B,KAAK,EAAE,KAAK,CAAA;IACZ,OAAO,EAAE,mBAAmB,CAAA;IAC5B,OAAO,CAAC,EAAE,cAAc,CAAA;CACzB;AAID,wBAAgB,YAAY,IAAI,KAAK,GAAG,SAAS,CAEhD;AAED,wBAAgB,cAAc,IAAI,mBAAmB,GAAG,SAAS,CAEhE;AAED,wBAAgB,cAAc,IAAI,cAAc,GAAG,SAAS,CAE3D;AAED,wBAAgB,0BAA0B,IAAI,OAAO,CAEpD;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EACrC,OAAO,EAAE,qBAAqB,EAC9B,QAAQ,EAAE,MAAM,MAAM,GACrB,MAAM,CAER;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EACxC,OAAO,EAAE;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,mBAAmB,CAAA;CAAE,EACvD,QAAQ,EAAE,MAAM,MAAM,GACrB,MAAM,CAER;AAED,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,MAAM,GAAG,MAAM,CAErF"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAShD,UAAU,qBAAqB;IAC7B,KAAK,EAAE,KAAK,CAAA;IACZ,OAAO,EAAE,YAAY,CAAA;IACrB,OAAO,CAAC,EAAE,cAAc,CAAA;CACzB;AAID,wBAAgB,YAAY,IAAI,KAAK,GAAG,SAAS,CAEhD;AAED,wBAAgB,cAAc,IAAI,YAAY,GAAG,SAAS,CAEzD;AAED,wBAAgB,cAAc,IAAI,cAAc,GAAG,SAAS,CAE3D;AAED,wBAAgB,0BAA0B,IAAI,OAAO,CAEpD;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EACrC,OAAO,EAAE,qBAAqB,EAC9B,QAAQ,EAAE,MAAM,MAAM,GACrB,MAAM,CAER;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EACxC,OAAO,EAAE;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,YAAY,CAAA;CAAE,EAChD,QAAQ,EAAE,MAAM,MAAM,GACrB,MAAM,CAER;AAED,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,MAAM,GAAG,MAAM,CAErF;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,MAAM,GAAG,MAAM,CAEzF"}
package/dist/context.js CHANGED
@@ -21,4 +21,7 @@ export function withActorProjection(context, callback) {
21
21
  export function withApplicationWritesForbidden(callback) {
22
22
  return storage.run({ ...storage.getStore(), applicationWritesForbidden: true }, callback);
23
23
  }
24
+ export function withRuntime(runtime, callback) {
25
+ return storage.run({ ...storage.getStore(), runtime }, callback);
26
+ }
24
27
  //# sourceMappingURL=context.js.map