@dxos/functions-runtime-cloudflare 0.8.4-main.66e292d → 0.8.4-main.6fa680abb7

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