@dxos/functions-runtime-cloudflare 0.8.4-main.1068cf700f

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 (52) hide show
  1. package/LICENSE +8 -0
  2. package/README.md +47 -0
  3. package/dist/lib/browser/index.mjs +1137 -0
  4. package/dist/lib/browser/index.mjs.map +7 -0
  5. package/dist/lib/browser/meta.json +1 -0
  6. package/dist/lib/node-esm/index.mjs +1139 -0
  7. package/dist/lib/node-esm/index.mjs.map +7 -0
  8. package/dist/lib/node-esm/meta.json +1 -0
  9. package/dist/types/src/functions-client.d.ts +33 -0
  10. package/dist/types/src/functions-client.d.ts.map +1 -0
  11. package/dist/types/src/index.d.ts +6 -0
  12. package/dist/types/src/index.d.ts.map +1 -0
  13. package/dist/types/src/internal/adapter.d.ts +12 -0
  14. package/dist/types/src/internal/adapter.d.ts.map +1 -0
  15. package/dist/types/src/internal/data-service-impl.d.ts +26 -0
  16. package/dist/types/src/internal/data-service-impl.d.ts.map +1 -0
  17. package/dist/types/src/internal/index.d.ts +2 -0
  18. package/dist/types/src/internal/index.d.ts.map +1 -0
  19. package/dist/types/src/internal/query-service-impl.d.ts +19 -0
  20. package/dist/types/src/internal/query-service-impl.d.ts.map +1 -0
  21. package/dist/types/src/internal/queue-service-impl.d.ts +10 -0
  22. package/dist/types/src/internal/queue-service-impl.d.ts.map +1 -0
  23. package/dist/types/src/internal/service-container.d.ts +25 -0
  24. package/dist/types/src/internal/service-container.d.ts.map +1 -0
  25. package/dist/types/src/internal/utils.d.ts +2 -0
  26. package/dist/types/src/internal/utils.d.ts.map +1 -0
  27. package/dist/types/src/logger.d.ts +2 -0
  28. package/dist/types/src/logger.d.ts.map +1 -0
  29. package/dist/types/src/queues-api.d.ts +22 -0
  30. package/dist/types/src/queues-api.d.ts.map +1 -0
  31. package/dist/types/src/space-proxy.d.ts +26 -0
  32. package/dist/types/src/space-proxy.d.ts.map +1 -0
  33. package/dist/types/src/types.d.ts +31 -0
  34. package/dist/types/src/types.d.ts.map +1 -0
  35. package/dist/types/src/wrap-handler-for-cloudflare.d.ts +6 -0
  36. package/dist/types/src/wrap-handler-for-cloudflare.d.ts.map +1 -0
  37. package/dist/types/tsconfig.tsbuildinfo +1 -0
  38. package/package.json +52 -0
  39. package/src/functions-client.ts +88 -0
  40. package/src/index.ts +9 -0
  41. package/src/internal/adapter.ts +48 -0
  42. package/src/internal/data-service-impl.ts +142 -0
  43. package/src/internal/index.ts +5 -0
  44. package/src/internal/query-service-impl.ts +107 -0
  45. package/src/internal/queue-service-impl.ts +62 -0
  46. package/src/internal/service-container.ts +71 -0
  47. package/src/internal/utils.ts +5 -0
  48. package/src/logger.ts +42 -0
  49. package/src/queues-api.ts +38 -0
  50. package/src/space-proxy.ts +66 -0
  51. package/src/types.ts +40 -0
  52. package/src/wrap-handler-for-cloudflare.ts +132 -0
@@ -0,0 +1,1139 @@
1
+ import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
+
3
+ // src/functions-client.ts
4
+ import { Resource as Resource2 } from "@dxos/context";
5
+ import { EchoClient } from "@dxos/echo-db";
6
+ import { invariant as invariant6 } from "@dxos/invariant";
7
+
8
+ // src/internal/data-service-impl.ts
9
+ import { Stream } from "@dxos/codec-protobuf/stream";
10
+ import { raise } from "@dxos/debug";
11
+ import { NotImplementedError, RuntimeServiceError } from "@dxos/errors";
12
+ import { invariant } from "@dxos/invariant";
13
+ import { SpaceId } from "@dxos/keys";
14
+ import { log } from "@dxos/log";
15
+
16
+ // src/internal/utils.ts
17
+ var copyUint8Array = (value) => new Uint8Array(value);
18
+
19
+ // src/internal/data-service-impl.ts
20
+ function _ts_add_disposable_resource(env, value, async) {
21
+ if (value !== null && value !== void 0) {
22
+ if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
23
+ var dispose, inner;
24
+ if (async) {
25
+ if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
26
+ dispose = value[Symbol.asyncDispose];
27
+ }
28
+ if (dispose === void 0) {
29
+ if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
30
+ dispose = value[Symbol.dispose];
31
+ if (async) inner = dispose;
32
+ }
33
+ if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
34
+ if (inner) dispose = function() {
35
+ try {
36
+ inner.call(this);
37
+ } catch (e) {
38
+ return Promise.reject(e);
39
+ }
40
+ };
41
+ env.stack.push({
42
+ value,
43
+ dispose,
44
+ async
45
+ });
46
+ } else if (async) {
47
+ env.stack.push({
48
+ async: true
49
+ });
50
+ }
51
+ return value;
52
+ }
53
+ function _ts_dispose_resources(env) {
54
+ var _SuppressedError = typeof SuppressedError === "function" ? SuppressedError : function(error, suppressed, message) {
55
+ var e = new Error(message);
56
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
57
+ };
58
+ return (_ts_dispose_resources = function _ts_dispose_resources5(env2) {
59
+ function fail(e) {
60
+ env2.error = env2.hasError ? new _SuppressedError(e, env2.error, "An error was suppressed during disposal.") : e;
61
+ env2.hasError = true;
62
+ }
63
+ var r, s = 0;
64
+ function next() {
65
+ while (r = env2.stack.pop()) {
66
+ try {
67
+ if (!r.async && s === 1) return s = 0, env2.stack.push(r), Promise.resolve().then(next);
68
+ if (r.dispose) {
69
+ var result = r.dispose.call(r.value);
70
+ if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) {
71
+ fail(e);
72
+ return next();
73
+ });
74
+ } else s |= 1;
75
+ } catch (e) {
76
+ fail(e);
77
+ }
78
+ }
79
+ if (s === 1) return env2.hasError ? Promise.reject(env2.error) : Promise.resolve();
80
+ if (env2.hasError) throw env2.error;
81
+ }
82
+ return next();
83
+ })(env);
84
+ }
85
+ var __dxlog_file = "/__w/dxos/dxos/packages/core/functions-runtime-cloudflare/src/internal/data-service-impl.ts";
86
+ var DataServiceImpl = class {
87
+ _executionContext;
88
+ _dataService;
89
+ dataSubscriptions = /* @__PURE__ */ new Map();
90
+ constructor(_executionContext, _dataService) {
91
+ this._executionContext = _executionContext;
92
+ this._dataService = _dataService;
93
+ }
94
+ subscribe({ subscriptionId, spaceId }) {
95
+ return new Stream(({ next }) => {
96
+ invariant(SpaceId.isValid(spaceId), void 0, {
97
+ F: __dxlog_file,
98
+ L: 39,
99
+ S: this,
100
+ A: [
101
+ "SpaceId.isValid(spaceId)",
102
+ ""
103
+ ]
104
+ });
105
+ this.dataSubscriptions.set(subscriptionId, {
106
+ spaceId,
107
+ next
108
+ });
109
+ return () => {
110
+ this.dataSubscriptions.delete(subscriptionId);
111
+ };
112
+ });
113
+ }
114
+ async updateSubscription({ subscriptionId, addIds }) {
115
+ const sub = this.dataSubscriptions.get(subscriptionId) ?? raise(new RuntimeServiceError({
116
+ message: "Subscription not found.",
117
+ context: {
118
+ subscriptionId
119
+ }
120
+ }));
121
+ if (addIds) {
122
+ log.info("request documents", {
123
+ count: addIds.length
124
+ }, {
125
+ F: __dxlog_file,
126
+ L: 59,
127
+ S: this,
128
+ C: (f, a) => f(...a)
129
+ });
130
+ for (const documentId of addIds) {
131
+ const env = {
132
+ stack: [],
133
+ error: void 0,
134
+ hasError: false
135
+ };
136
+ try {
137
+ const document = _ts_add_disposable_resource(env, await this._dataService.getDocument(this._executionContext, sub.spaceId, documentId), false);
138
+ log.info("document loaded", {
139
+ documentId,
140
+ spaceId: sub.spaceId,
141
+ found: !!document
142
+ }, {
143
+ F: __dxlog_file,
144
+ L: 63,
145
+ S: this,
146
+ C: (f, a) => f(...a)
147
+ });
148
+ if (!document) {
149
+ log.warn("not found", {
150
+ documentId
151
+ }, {
152
+ F: __dxlog_file,
153
+ L: 65,
154
+ S: this,
155
+ C: (f, a) => f(...a)
156
+ });
157
+ continue;
158
+ }
159
+ sub.next({
160
+ updates: [
161
+ {
162
+ documentId,
163
+ // Copy returned object to avoid hanging RPC stub
164
+ // See https://developers.cloudflare.com/workers/runtime-apis/rpc/lifecycle/
165
+ mutation: copyUint8Array(document.data)
166
+ }
167
+ ]
168
+ });
169
+ } catch (e) {
170
+ env.error = e;
171
+ env.hasError = true;
172
+ } finally {
173
+ _ts_dispose_resources(env);
174
+ }
175
+ }
176
+ }
177
+ }
178
+ async createDocument({ spaceId, initialValue }) {
179
+ const env = {
180
+ stack: [],
181
+ error: void 0,
182
+ hasError: false
183
+ };
184
+ try {
185
+ const response = _ts_add_disposable_resource(env, await this._dataService.createDocument(this._executionContext, {
186
+ spaceId,
187
+ initialValue
188
+ }), false);
189
+ return {
190
+ documentId: response.documentId
191
+ };
192
+ } catch (e) {
193
+ env.error = e;
194
+ env.hasError = true;
195
+ } finally {
196
+ _ts_dispose_resources(env);
197
+ }
198
+ }
199
+ async update({ updates, subscriptionId }) {
200
+ const sub = this.dataSubscriptions.get(subscriptionId) ?? raise(new RuntimeServiceError({
201
+ message: "Subscription not found.",
202
+ context: {
203
+ subscriptionId
204
+ }
205
+ }));
206
+ try {
207
+ for (const update of updates ?? []) {
208
+ await this._dataService.changeDocument(this._executionContext, sub.spaceId, update.documentId, update.mutation);
209
+ }
210
+ } catch (error) {
211
+ throw RuntimeServiceError.wrap({
212
+ message: "Failed to apply document updates.",
213
+ context: {
214
+ subscriptionId
215
+ },
216
+ ifTypeDiffers: true
217
+ })(error);
218
+ }
219
+ }
220
+ async flush() {
221
+ }
222
+ subscribeSpaceSyncState(_request, _options) {
223
+ throw new NotImplementedError({
224
+ message: "subscribeSpaceSyncState is not implemented."
225
+ });
226
+ }
227
+ async getDocumentHeads({ documentIds: _documentIds }) {
228
+ throw new NotImplementedError({
229
+ message: "getDocumentHeads is not implemented."
230
+ });
231
+ }
232
+ async reIndexHeads({ documentIds: _documentIds }) {
233
+ throw new NotImplementedError({
234
+ message: "reIndexHeads is not implemented."
235
+ });
236
+ }
237
+ async updateIndexes() {
238
+ log.error("updateIndexes is not available in EDGE env.", void 0, {
239
+ F: __dxlog_file,
240
+ L: 133,
241
+ S: this,
242
+ C: (f, a) => f(...a)
243
+ });
244
+ }
245
+ async waitUntilHeadsReplicated({ heads: _heads }) {
246
+ throw new NotImplementedError({
247
+ message: "waitUntilHeadsReplicated is not implemented."
248
+ });
249
+ }
250
+ };
251
+
252
+ // src/internal/query-service-impl.ts
253
+ import * as Schema from "effect/Schema";
254
+ import { Stream as Stream2 } from "@dxos/codec-protobuf/stream";
255
+ import { QueryAST } from "@dxos/echo-protocol";
256
+ import { NotImplementedError as NotImplementedError2, RuntimeServiceError as RuntimeServiceError2 } from "@dxos/errors";
257
+ import { invariant as invariant3 } from "@dxos/invariant";
258
+ import { PublicKey } from "@dxos/keys";
259
+ import { SpaceId as SpaceId3 } from "@dxos/keys";
260
+ import { log as log2 } from "@dxos/log";
261
+
262
+ // src/internal/adapter.ts
263
+ import { failUndefined } from "@dxos/debug";
264
+ import { invariant as invariant2 } from "@dxos/invariant";
265
+ import { SpaceId as SpaceId2 } from "@dxos/keys";
266
+ var __dxlog_file2 = "/__w/dxos/dxos/packages/core/functions-runtime-cloudflare/src/internal/adapter.ts";
267
+ var queryToDataServiceRequest = (query) => {
268
+ const { filter, options } = isSimpleSelectionQuery(query) ?? failUndefined();
269
+ invariant2(options?.spaceIds?.length === 1, "Only one space is supported", {
270
+ F: __dxlog_file2,
271
+ L: 13,
272
+ S: void 0,
273
+ A: [
274
+ "options?.spaceIds?.length === 1",
275
+ "'Only one space is supported'"
276
+ ]
277
+ });
278
+ invariant2(filter.type === "object", "Only object filters are supported", {
279
+ F: __dxlog_file2,
280
+ L: 14,
281
+ S: void 0,
282
+ A: [
283
+ "filter.type === 'object'",
284
+ "'Only object filters are supported'"
285
+ ]
286
+ });
287
+ const spaceId = options.spaceIds[0];
288
+ invariant2(SpaceId2.isValid(spaceId), void 0, {
289
+ F: __dxlog_file2,
290
+ L: 17,
291
+ S: void 0,
292
+ A: [
293
+ "SpaceId.isValid(spaceId)",
294
+ ""
295
+ ]
296
+ });
297
+ return {
298
+ spaceId,
299
+ type: filter.typename ?? void 0,
300
+ objectIds: [
301
+ ...filter.id ?? []
302
+ ]
303
+ };
304
+ };
305
+ var isSimpleSelectionQuery = (query) => {
306
+ switch (query.type) {
307
+ case "options": {
308
+ const maybeFilter = isSimpleSelectionQuery(query.query);
309
+ if (!maybeFilter) {
310
+ return null;
311
+ }
312
+ return {
313
+ filter: maybeFilter.filter,
314
+ options: query.options
315
+ };
316
+ }
317
+ case "select": {
318
+ return {
319
+ filter: query.filter,
320
+ options: void 0
321
+ };
322
+ }
323
+ default: {
324
+ return null;
325
+ }
326
+ }
327
+ };
328
+
329
+ // src/internal/query-service-impl.ts
330
+ function _ts_add_disposable_resource2(env, value, async) {
331
+ if (value !== null && value !== void 0) {
332
+ if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
333
+ var dispose, inner;
334
+ if (async) {
335
+ if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
336
+ dispose = value[Symbol.asyncDispose];
337
+ }
338
+ if (dispose === void 0) {
339
+ if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
340
+ dispose = value[Symbol.dispose];
341
+ if (async) inner = dispose;
342
+ }
343
+ if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
344
+ if (inner) dispose = function() {
345
+ try {
346
+ inner.call(this);
347
+ } catch (e) {
348
+ return Promise.reject(e);
349
+ }
350
+ };
351
+ env.stack.push({
352
+ value,
353
+ dispose,
354
+ async
355
+ });
356
+ } else if (async) {
357
+ env.stack.push({
358
+ async: true
359
+ });
360
+ }
361
+ return value;
362
+ }
363
+ function _ts_dispose_resources2(env) {
364
+ var _SuppressedError = typeof SuppressedError === "function" ? SuppressedError : function(error, suppressed, message) {
365
+ var e = new Error(message);
366
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
367
+ };
368
+ return (_ts_dispose_resources2 = function _ts_dispose_resources5(env2) {
369
+ function fail(e) {
370
+ env2.error = env2.hasError ? new _SuppressedError(e, env2.error, "An error was suppressed during disposal.") : e;
371
+ env2.hasError = true;
372
+ }
373
+ var r, s = 0;
374
+ function next() {
375
+ while (r = env2.stack.pop()) {
376
+ try {
377
+ if (!r.async && s === 1) return s = 0, env2.stack.push(r), Promise.resolve().then(next);
378
+ if (r.dispose) {
379
+ var result = r.dispose.call(r.value);
380
+ if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) {
381
+ fail(e);
382
+ return next();
383
+ });
384
+ } else s |= 1;
385
+ } catch (e) {
386
+ fail(e);
387
+ }
388
+ }
389
+ if (s === 1) return env2.hasError ? Promise.reject(env2.error) : Promise.resolve();
390
+ if (env2.hasError) throw env2.error;
391
+ }
392
+ return next();
393
+ })(env);
394
+ }
395
+ var __dxlog_file3 = "/__w/dxos/dxos/packages/core/functions-runtime-cloudflare/src/internal/query-service-impl.ts";
396
+ var QueryServiceImpl = class {
397
+ _executionContext;
398
+ _dataService;
399
+ _queryCount = 0;
400
+ constructor(_executionContext, _dataService) {
401
+ this._executionContext = _executionContext;
402
+ this._dataService = _dataService;
403
+ }
404
+ execQuery(request) {
405
+ log2.info("execQuery", {
406
+ request
407
+ }, {
408
+ F: __dxlog_file3,
409
+ L: 34,
410
+ S: this,
411
+ C: (f, a) => f(...a)
412
+ });
413
+ const query = QueryAST.Query.pipe(Schema.decodeUnknownSync)(JSON.parse(request.query));
414
+ const requestedSpaceIds = getTargetSpacesForQuery(query);
415
+ invariant3(requestedSpaceIds.length === 1, "Only one space is supported", {
416
+ F: __dxlog_file3,
417
+ L: 37,
418
+ S: this,
419
+ A: [
420
+ "requestedSpaceIds.length === 1",
421
+ "'Only one space is supported'"
422
+ ]
423
+ });
424
+ const spaceId = requestedSpaceIds[0];
425
+ return Stream2.fromPromise((async () => {
426
+ try {
427
+ const env = {
428
+ stack: [],
429
+ error: void 0,
430
+ hasError: false
431
+ };
432
+ try {
433
+ this._queryCount++;
434
+ log2.info("begin query", {
435
+ spaceId
436
+ }, {
437
+ F: __dxlog_file3,
438
+ L: 44,
439
+ S: this,
440
+ C: (f, a) => f(...a)
441
+ });
442
+ const queryResponse = _ts_add_disposable_resource2(env, await this._dataService.queryDocuments(this._executionContext, queryToDataServiceRequest(query)), false);
443
+ log2.info("query response", {
444
+ spaceId,
445
+ filter: request.filter,
446
+ resultCount: queryResponse.results.length
447
+ }, {
448
+ F: __dxlog_file3,
449
+ L: 49,
450
+ S: this,
451
+ C: (f, a) => f(...a)
452
+ });
453
+ return {
454
+ results: queryResponse.results.map((object) => ({
455
+ id: object.objectId,
456
+ spaceId,
457
+ spaceKey: PublicKey.ZERO,
458
+ documentId: object.document.documentId,
459
+ // Rank 1 for predicate matches where ranking is not determined.
460
+ rank: 1,
461
+ // Copy returned object to avoid hanging RPC stub.
462
+ // See https://developers.cloudflare.com/workers/runtime-apis/rpc/lifecycle/
463
+ documentAutomerge: copyUint8Array(object.document.data)
464
+ }))
465
+ };
466
+ } catch (e) {
467
+ env.error = e;
468
+ env.hasError = true;
469
+ } finally {
470
+ _ts_dispose_resources2(env);
471
+ }
472
+ } catch (error) {
473
+ log2.error("query failed", {
474
+ err: error
475
+ }, {
476
+ F: __dxlog_file3,
477
+ L: 66,
478
+ S: this,
479
+ C: (f, a) => f(...a)
480
+ });
481
+ throw new RuntimeServiceError2({
482
+ message: `Query execution failed (queryCount=${this._queryCount})`,
483
+ context: {
484
+ spaceId,
485
+ filter: request.filter,
486
+ queryCount: this._queryCount
487
+ },
488
+ cause: error
489
+ });
490
+ }
491
+ })());
492
+ }
493
+ async reindex() {
494
+ throw new NotImplementedError2({
495
+ message: "Reindex is not implemented."
496
+ });
497
+ }
498
+ async setConfig() {
499
+ throw new NotImplementedError2({
500
+ message: "SetConfig is not implemented."
501
+ });
502
+ }
503
+ };
504
+ var getTargetSpacesForQuery = (query) => {
505
+ const spaces = /* @__PURE__ */ new Set();
506
+ const visitor = (node) => {
507
+ if (node.type === "options") {
508
+ if (node.options.spaceIds) {
509
+ for (const spaceId of node.options.spaceIds) {
510
+ spaces.add(SpaceId3.make(spaceId));
511
+ }
512
+ }
513
+ }
514
+ };
515
+ QueryAST.visit(query, visitor);
516
+ return [
517
+ ...spaces
518
+ ];
519
+ };
520
+
521
+ // src/internal/queue-service-impl.ts
522
+ import { NotImplementedError as NotImplementedError3, RuntimeServiceError as RuntimeServiceError3 } from "@dxos/errors";
523
+ import { invariant as invariant4 } from "@dxos/invariant";
524
+ function _ts_add_disposable_resource3(env, value, async) {
525
+ if (value !== null && value !== void 0) {
526
+ if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
527
+ var dispose, inner;
528
+ if (async) {
529
+ if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
530
+ dispose = value[Symbol.asyncDispose];
531
+ }
532
+ if (dispose === void 0) {
533
+ if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
534
+ dispose = value[Symbol.dispose];
535
+ if (async) inner = dispose;
536
+ }
537
+ if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
538
+ if (inner) dispose = function() {
539
+ try {
540
+ inner.call(this);
541
+ } catch (e) {
542
+ return Promise.reject(e);
543
+ }
544
+ };
545
+ env.stack.push({
546
+ value,
547
+ dispose,
548
+ async
549
+ });
550
+ } else if (async) {
551
+ env.stack.push({
552
+ async: true
553
+ });
554
+ }
555
+ return value;
556
+ }
557
+ function _ts_dispose_resources3(env) {
558
+ var _SuppressedError = typeof SuppressedError === "function" ? SuppressedError : function(error, suppressed, message) {
559
+ var e = new Error(message);
560
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
561
+ };
562
+ return (_ts_dispose_resources3 = function _ts_dispose_resources5(env2) {
563
+ function fail(e) {
564
+ env2.error = env2.hasError ? new _SuppressedError(e, env2.error, "An error was suppressed during disposal.") : e;
565
+ env2.hasError = true;
566
+ }
567
+ var r, s = 0;
568
+ function next() {
569
+ while (r = env2.stack.pop()) {
570
+ try {
571
+ if (!r.async && s === 1) return s = 0, env2.stack.push(r), Promise.resolve().then(next);
572
+ if (r.dispose) {
573
+ var result = r.dispose.call(r.value);
574
+ if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) {
575
+ fail(e);
576
+ return next();
577
+ });
578
+ } else s |= 1;
579
+ } catch (e) {
580
+ fail(e);
581
+ }
582
+ }
583
+ if (s === 1) return env2.hasError ? Promise.reject(env2.error) : Promise.resolve();
584
+ if (env2.hasError) throw env2.error;
585
+ }
586
+ return next();
587
+ })(env);
588
+ }
589
+ var __dxlog_file4 = "/__w/dxos/dxos/packages/core/functions-runtime-cloudflare/src/internal/queue-service-impl.ts";
590
+ var QueueServiceImpl = class {
591
+ _ctx;
592
+ _queueService;
593
+ constructor(_ctx, _queueService) {
594
+ this._ctx = _ctx;
595
+ this._queueService = _queueService;
596
+ }
597
+ async queryQueue(request) {
598
+ const { query } = request;
599
+ const { queueIds, ...filter } = query;
600
+ const spaceId = query.spaceId;
601
+ const queueId = queueIds?.[0];
602
+ invariant4(request.query.queuesNamespace, void 0, {
603
+ F: __dxlog_file4,
604
+ L: 19,
605
+ S: this,
606
+ A: [
607
+ "request.query.queuesNamespace",
608
+ ""
609
+ ]
610
+ });
611
+ try {
612
+ const env = {
613
+ stack: [],
614
+ error: void 0,
615
+ hasError: false
616
+ };
617
+ try {
618
+ const result = _ts_add_disposable_resource3(env, await this._queueService.query(this._ctx, `dxn:queue:${request.query.queuesNamespace}:${spaceId}:${queueId}`, filter), false);
619
+ return {
620
+ // Copy returned object to avoid hanging RPC stub
621
+ // See https://developers.cloudflare.com/workers/runtime-apis/rpc/lifecycle/
622
+ objects: structuredClone(result.objects),
623
+ nextCursor: result.nextCursor,
624
+ prevCursor: result.prevCursor
625
+ };
626
+ } catch (e) {
627
+ env.error = e;
628
+ env.hasError = true;
629
+ } finally {
630
+ _ts_dispose_resources3(env);
631
+ }
632
+ } catch (error) {
633
+ throw RuntimeServiceError3.wrap({
634
+ message: "Queue query failed.",
635
+ context: {
636
+ subspaceTag: request.query.queuesNamespace,
637
+ spaceId,
638
+ queueId
639
+ },
640
+ ifTypeDiffers: true
641
+ })(error);
642
+ }
643
+ }
644
+ async insertIntoQueue(request) {
645
+ const { subspaceTag, spaceId, queueId, objects } = request;
646
+ try {
647
+ await this._queueService.append(this._ctx, `dxn:queue:${subspaceTag}:${spaceId}:${queueId}`, objects ?? []);
648
+ } catch (error) {
649
+ throw RuntimeServiceError3.wrap({
650
+ message: "Queue append failed.",
651
+ context: {
652
+ subspaceTag,
653
+ spaceId,
654
+ queueId
655
+ },
656
+ ifTypeDiffers: true
657
+ })(error);
658
+ }
659
+ }
660
+ deleteFromQueue(request) {
661
+ const { subspaceTag, spaceId, queueId } = request;
662
+ throw new NotImplementedError3({
663
+ message: "Deleting from queue is not supported.",
664
+ context: {
665
+ subspaceTag,
666
+ spaceId,
667
+ queueId
668
+ }
669
+ });
670
+ }
671
+ };
672
+
673
+ // src/internal/service-container.ts
674
+ function _ts_add_disposable_resource4(env, value, async) {
675
+ if (value !== null && value !== void 0) {
676
+ if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
677
+ var dispose, inner;
678
+ if (async) {
679
+ if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
680
+ dispose = value[Symbol.asyncDispose];
681
+ }
682
+ if (dispose === void 0) {
683
+ if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
684
+ dispose = value[Symbol.dispose];
685
+ if (async) inner = dispose;
686
+ }
687
+ if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
688
+ if (inner) dispose = function() {
689
+ try {
690
+ inner.call(this);
691
+ } catch (e) {
692
+ return Promise.reject(e);
693
+ }
694
+ };
695
+ env.stack.push({
696
+ value,
697
+ dispose,
698
+ async
699
+ });
700
+ } else if (async) {
701
+ env.stack.push({
702
+ async: true
703
+ });
704
+ }
705
+ return value;
706
+ }
707
+ function _ts_dispose_resources4(env) {
708
+ var _SuppressedError = typeof SuppressedError === "function" ? SuppressedError : function(error, suppressed, message) {
709
+ var e = new Error(message);
710
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
711
+ };
712
+ return (_ts_dispose_resources4 = function _ts_dispose_resources5(env2) {
713
+ function fail(e) {
714
+ env2.error = env2.hasError ? new _SuppressedError(e, env2.error, "An error was suppressed during disposal.") : e;
715
+ env2.hasError = true;
716
+ }
717
+ var r, s = 0;
718
+ function next() {
719
+ while (r = env2.stack.pop()) {
720
+ try {
721
+ if (!r.async && s === 1) return s = 0, env2.stack.push(r), Promise.resolve().then(next);
722
+ if (r.dispose) {
723
+ var result = r.dispose.call(r.value);
724
+ if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) {
725
+ fail(e);
726
+ return next();
727
+ });
728
+ } else s |= 1;
729
+ } catch (e) {
730
+ fail(e);
731
+ }
732
+ }
733
+ if (s === 1) return env2.hasError ? Promise.reject(env2.error) : Promise.resolve();
734
+ if (env2.hasError) throw env2.error;
735
+ }
736
+ return next();
737
+ })(env);
738
+ }
739
+ var ServiceContainer = class {
740
+ _executionContext;
741
+ _dataService;
742
+ _queueService;
743
+ _functionsService;
744
+ constructor(_executionContext, _dataService, _queueService, _functionsService) {
745
+ this._executionContext = _executionContext;
746
+ this._dataService = _dataService;
747
+ this._queueService = _queueService;
748
+ this._functionsService = _functionsService;
749
+ }
750
+ async getSpaceMeta(spaceId) {
751
+ const env = {
752
+ stack: [],
753
+ error: void 0,
754
+ hasError: false
755
+ };
756
+ try {
757
+ const result = _ts_add_disposable_resource4(env, await this._dataService.getSpaceMeta(this._executionContext, spaceId), false);
758
+ return result ? {
759
+ spaceKey: result.spaceKey,
760
+ rootDocumentId: result.rootDocumentId
761
+ } : void 0;
762
+ } catch (e) {
763
+ env.error = e;
764
+ env.hasError = true;
765
+ } finally {
766
+ _ts_dispose_resources4(env);
767
+ }
768
+ }
769
+ async createServices() {
770
+ const dataService = new DataServiceImpl(this._executionContext, this._dataService);
771
+ const queryService = new QueryServiceImpl(this._executionContext, this._dataService);
772
+ const queueService = new QueueServiceImpl(this._executionContext, this._queueService);
773
+ return {
774
+ dataService,
775
+ queryService,
776
+ queueService,
777
+ functionsAiService: this._functionsService
778
+ };
779
+ }
780
+ async queryQueue(queue) {
781
+ const env = {
782
+ stack: [],
783
+ error: void 0,
784
+ hasError: false
785
+ };
786
+ try {
787
+ const { spaceId } = queue.asQueueDXN() ?? {};
788
+ const result = _ts_add_disposable_resource4(env, await this._queueService.query({}, queue.toString(), {
789
+ spaceId
790
+ }), false);
791
+ return {
792
+ objects: structuredClone(result.objects),
793
+ nextCursor: result.nextCursor ?? null,
794
+ prevCursor: result.prevCursor ?? null
795
+ };
796
+ } catch (e) {
797
+ env.error = e;
798
+ env.hasError = true;
799
+ } finally {
800
+ _ts_dispose_resources4(env);
801
+ }
802
+ }
803
+ async insertIntoQueue(queue, objects) {
804
+ await this._queueService.append({}, queue.toString(), objects);
805
+ }
806
+ };
807
+
808
+ // src/space-proxy.ts
809
+ import { Resource } from "@dxos/context";
810
+ import { invariant as invariant5 } from "@dxos/invariant";
811
+ import { PublicKey as PublicKey2 } from "@dxos/keys";
812
+
813
+ // src/queues-api.ts
814
+ var QueuesAPIImpl = class {
815
+ _serviceContainer;
816
+ _spaceId;
817
+ constructor(_serviceContainer, _spaceId) {
818
+ this._serviceContainer = _serviceContainer;
819
+ this._spaceId = _spaceId;
820
+ }
821
+ queryQueue(queue, options) {
822
+ return this._serviceContainer.queryQueue(queue);
823
+ }
824
+ insertIntoQueue(queue, objects) {
825
+ return this._serviceContainer.insertIntoQueue(queue, JSON.parse(JSON.stringify(objects)));
826
+ }
827
+ };
828
+
829
+ // src/space-proxy.ts
830
+ var __dxlog_file5 = "/__w/dxos/dxos/packages/core/functions-runtime-cloudflare/src/space-proxy.ts";
831
+ var SpaceProxy = class extends Resource {
832
+ _serviceContainer;
833
+ _echoClient;
834
+ _id;
835
+ _db = void 0;
836
+ _queuesApi;
837
+ constructor(_serviceContainer, _echoClient, _id) {
838
+ super(), this._serviceContainer = _serviceContainer, this._echoClient = _echoClient, this._id = _id;
839
+ this._queuesApi = new QueuesAPIImpl(this._serviceContainer, this._id);
840
+ }
841
+ get id() {
842
+ return this._id;
843
+ }
844
+ get db() {
845
+ invariant5(this._db, void 0, {
846
+ F: __dxlog_file5,
847
+ L: 35,
848
+ S: this,
849
+ A: [
850
+ "this._db",
851
+ ""
852
+ ]
853
+ });
854
+ return this._db;
855
+ }
856
+ /**
857
+ * @deprecated Use db API.
858
+ */
859
+ get crud() {
860
+ invariant5(this._db, void 0, {
861
+ F: __dxlog_file5,
862
+ L: 43,
863
+ S: this,
864
+ A: [
865
+ "this._db",
866
+ ""
867
+ ]
868
+ });
869
+ return this._db.coreDatabase;
870
+ }
871
+ get queues() {
872
+ return this._queuesApi;
873
+ }
874
+ async _open() {
875
+ const meta = await this._serviceContainer.getSpaceMeta(this._id);
876
+ if (!meta) {
877
+ throw new Error(`Space not found: ${this._id}`);
878
+ }
879
+ this._db = this._echoClient.constructDatabase({
880
+ spaceId: this._id,
881
+ spaceKey: PublicKey2.from(meta.spaceKey),
882
+ reactiveSchemaQuery: false,
883
+ owningObject: this
884
+ });
885
+ await this._db.coreDatabase.open({
886
+ rootUrl: meta.rootDocumentId
887
+ });
888
+ }
889
+ };
890
+
891
+ // src/functions-client.ts
892
+ var __dxlog_file6 = "/__w/dxos/dxos/packages/core/functions-runtime-cloudflare/src/functions-client.ts";
893
+ var FunctionsClient = class extends Resource2 {
894
+ _serviceContainer;
895
+ _echoClient;
896
+ _executionContext = {};
897
+ _spaces = /* @__PURE__ */ new Map();
898
+ constructor(services) {
899
+ super();
900
+ invariant6(typeof services.dataService !== "undefined", "DataService is required", {
901
+ F: __dxlog_file6,
902
+ L: 33,
903
+ S: this,
904
+ A: [
905
+ "typeof services.dataService !== 'undefined'",
906
+ "'DataService is required'"
907
+ ]
908
+ });
909
+ invariant6(typeof services.queueService !== "undefined", "QueueService is required", {
910
+ F: __dxlog_file6,
911
+ L: 34,
912
+ S: this,
913
+ A: [
914
+ "typeof services.queueService !== 'undefined'",
915
+ "'QueueService is required'"
916
+ ]
917
+ });
918
+ this._serviceContainer = new ServiceContainer(this._executionContext, services.dataService, services.queueService, services.functionsAiService);
919
+ this._echoClient = new EchoClient({});
920
+ }
921
+ get echo() {
922
+ return this._echoClient;
923
+ }
924
+ async _open() {
925
+ const { dataService, queryService } = await this._serviceContainer.createServices();
926
+ this._echoClient.connectToService({
927
+ dataService,
928
+ queryService
929
+ });
930
+ await this._echoClient.open();
931
+ }
932
+ async _close() {
933
+ for (const space of this._spaces.values()) {
934
+ await space.close();
935
+ }
936
+ this._spaces.clear();
937
+ await this._echoClient.close();
938
+ }
939
+ async getSpace(spaceId) {
940
+ if (!this._spaces.has(spaceId)) {
941
+ const space2 = new SpaceProxy(this._serviceContainer, this._echoClient, spaceId);
942
+ this._spaces.set(spaceId, space2);
943
+ }
944
+ const space = this._spaces.get(spaceId);
945
+ await space.open();
946
+ return space;
947
+ }
948
+ };
949
+ var createClientFromEnv = async (env) => {
950
+ const client = new FunctionsClient({
951
+ dataService: env.DATA_SERVICE,
952
+ queueService: env.QUEUE_SERVICE,
953
+ functionsAiService: env.FUNCTIONS_AI_SERVICE
954
+ });
955
+ await client.open();
956
+ return client;
957
+ };
958
+
959
+ // src/types.ts
960
+ var FUNCTION_ROUTE_HEADER = "X-DXOS-Function-Route";
961
+ var FunctionRouteValue = /* @__PURE__ */ (function(FunctionRouteValue2) {
962
+ FunctionRouteValue2["Meta"] = "meta";
963
+ return FunctionRouteValue2;
964
+ })({});
965
+
966
+ // src/wrap-handler-for-cloudflare.ts
967
+ import { invariant as invariant7 } from "@dxos/invariant";
968
+ import { SpaceId as SpaceId4 } from "@dxos/keys";
969
+ import { log as log3 } from "@dxos/log";
970
+ import { EdgeResponse } from "@dxos/protocols";
971
+ var __dxlog_file7 = "/__w/dxos/dxos/packages/core/functions-runtime-cloudflare/src/wrap-handler-for-cloudflare.ts";
972
+ var wrapHandlerForCloudflare = (func) => {
973
+ return async (request, env) => {
974
+ if (request.headers.get(FUNCTION_ROUTE_HEADER) === FunctionRouteValue.Meta) {
975
+ return handleFunctionMetaCall(func, request);
976
+ }
977
+ try {
978
+ const spaceId = new URL(request.url).searchParams.get("spaceId");
979
+ if (spaceId) {
980
+ if (!SpaceId4.isValid(spaceId)) {
981
+ return new Response("Invalid spaceId", {
982
+ status: 400
983
+ });
984
+ }
985
+ }
986
+ const serviceContainer = new ServiceContainer({}, env.DATA_SERVICE, env.QUEUE_SERVICE, env.FUNCTIONS_AI_SERVICE);
987
+ const context = await createFunctionContext({
988
+ serviceContainer,
989
+ contextSpaceId: spaceId
990
+ });
991
+ return EdgeResponse.success(await invokeFunction(func, context, request));
992
+ } catch (error) {
993
+ log3.error("error invoking function", {
994
+ error,
995
+ stack: error.stack
996
+ }, {
997
+ F: __dxlog_file7,
998
+ L: 44,
999
+ S: void 0,
1000
+ C: (f, a) => f(...a)
1001
+ });
1002
+ return EdgeResponse.failure({
1003
+ message: error?.message ?? "Internal error",
1004
+ error
1005
+ });
1006
+ }
1007
+ };
1008
+ };
1009
+ var invokeFunction = async (func, context, request) => {
1010
+ const { data } = await decodeRequest(request);
1011
+ return func.handler({
1012
+ context,
1013
+ data
1014
+ });
1015
+ };
1016
+ var decodeRequest = async (request) => {
1017
+ const { data: { bodyText, ...rest }, trigger } = await request.json();
1018
+ if (!bodyText) {
1019
+ return {
1020
+ data: rest,
1021
+ trigger
1022
+ };
1023
+ }
1024
+ try {
1025
+ const data = JSON.parse(bodyText);
1026
+ return {
1027
+ data,
1028
+ trigger: {
1029
+ ...trigger,
1030
+ ...rest
1031
+ }
1032
+ };
1033
+ } catch (err) {
1034
+ log3.catch(err, void 0, {
1035
+ F: __dxlog_file7,
1036
+ L: 79,
1037
+ S: void 0,
1038
+ C: (f, a) => f(...a)
1039
+ });
1040
+ return {
1041
+ data: {
1042
+ bodyText,
1043
+ ...rest
1044
+ }
1045
+ };
1046
+ }
1047
+ };
1048
+ var handleFunctionMetaCall = (functionDefinition, request) => {
1049
+ const response = {
1050
+ key: functionDefinition.meta.key,
1051
+ name: functionDefinition.meta.name,
1052
+ description: functionDefinition.meta.description,
1053
+ inputSchema: functionDefinition.meta.inputSchema,
1054
+ outputSchema: functionDefinition.meta.outputSchema
1055
+ };
1056
+ return new Response(JSON.stringify(response), {
1057
+ headers: {
1058
+ "Content-Type": "application/json"
1059
+ }
1060
+ });
1061
+ };
1062
+ var createFunctionContext = async ({ serviceContainer, contextSpaceId }) => {
1063
+ const { dataService, queryService, queueService, functionsAiService } = await serviceContainer.createServices();
1064
+ let spaceKey;
1065
+ let rootUrl;
1066
+ if (contextSpaceId) {
1067
+ const meta = await serviceContainer.getSpaceMeta(contextSpaceId);
1068
+ if (!meta) {
1069
+ throw new Error(`Space not found: ${contextSpaceId}`);
1070
+ }
1071
+ spaceKey = meta.spaceKey;
1072
+ invariant7(!meta.rootDocumentId.startsWith("automerge:"), void 0, {
1073
+ F: __dxlog_file7,
1074
+ L: 117,
1075
+ S: void 0,
1076
+ A: [
1077
+ "!meta.rootDocumentId.startsWith('automerge:')",
1078
+ ""
1079
+ ]
1080
+ });
1081
+ rootUrl = `automerge:${meta.rootDocumentId}`;
1082
+ }
1083
+ return {
1084
+ services: {
1085
+ dataService,
1086
+ queryService,
1087
+ queueService,
1088
+ functionsAiService
1089
+ },
1090
+ spaceId: contextSpaceId,
1091
+ spaceKey,
1092
+ spaceRootUrl: rootUrl
1093
+ };
1094
+ };
1095
+
1096
+ // src/logger.ts
1097
+ import { LogLevel, log as log4, shouldLog } from "@dxos/log";
1098
+ var setupFunctionsLogger = () => {
1099
+ log4.runtimeConfig.processors.length = 0;
1100
+ log4.runtimeConfig.processors.push(functionLogProcessor);
1101
+ };
1102
+ var functionLogProcessor = (config, entry) => {
1103
+ if (!shouldLog(entry, config.filters)) {
1104
+ return;
1105
+ }
1106
+ switch (entry.level) {
1107
+ case LogLevel.DEBUG:
1108
+ console.debug(entry.message, entry.context);
1109
+ break;
1110
+ case LogLevel.TRACE:
1111
+ console.debug(entry.message, entry.context);
1112
+ break;
1113
+ case LogLevel.VERBOSE:
1114
+ console.log(entry.message, entry.context);
1115
+ break;
1116
+ case LogLevel.INFO:
1117
+ console.info(entry.message, entry.context);
1118
+ break;
1119
+ case LogLevel.WARN:
1120
+ console.warn(entry.message, entry.context);
1121
+ break;
1122
+ case LogLevel.ERROR:
1123
+ console.error(entry.message, entry.context);
1124
+ break;
1125
+ default:
1126
+ console.log(entry.message, entry.context);
1127
+ break;
1128
+ }
1129
+ };
1130
+ export {
1131
+ FUNCTION_ROUTE_HEADER,
1132
+ FunctionRouteValue,
1133
+ FunctionsClient,
1134
+ ServiceContainer,
1135
+ createClientFromEnv,
1136
+ setupFunctionsLogger,
1137
+ wrapHandlerForCloudflare
1138
+ };
1139
+ //# sourceMappingURL=index.mjs.map