@dxos/effect 0.8.4-main.70d3990 → 0.8.4-main.74a063c4e0

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/dist/lib/browser/chunk-CGS2ULMK.mjs +11 -0
  2. package/dist/lib/browser/chunk-CGS2ULMK.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +395 -238
  4. package/dist/lib/browser/index.mjs.map +4 -4
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/browser/testing.mjs +39 -0
  7. package/dist/lib/browser/testing.mjs.map +7 -0
  8. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
  9. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +7 -0
  10. package/dist/lib/node-esm/index.mjs +395 -238
  11. package/dist/lib/node-esm/index.mjs.map +4 -4
  12. package/dist/lib/node-esm/meta.json +1 -1
  13. package/dist/lib/node-esm/testing.mjs +39 -0
  14. package/dist/lib/node-esm/testing.mjs.map +7 -0
  15. package/dist/types/src/Performance.d.ts +25 -0
  16. package/dist/types/src/Performance.d.ts.map +1 -0
  17. package/dist/types/src/RuntimeProvider.d.ts +21 -0
  18. package/dist/types/src/RuntimeProvider.d.ts.map +1 -0
  19. package/dist/types/src/ast.d.ts +33 -20
  20. package/dist/types/src/ast.d.ts.map +1 -1
  21. package/dist/types/src/atom-kvs.d.ts +19 -0
  22. package/dist/types/src/atom-kvs.d.ts.map +1 -0
  23. package/dist/types/src/dynamic-runtime.d.ts +56 -0
  24. package/dist/types/src/dynamic-runtime.d.ts.map +1 -0
  25. package/dist/types/src/dynamic-runtime.test.d.ts +2 -0
  26. package/dist/types/src/dynamic-runtime.test.d.ts.map +1 -0
  27. package/dist/types/src/errors.d.ts +12 -0
  28. package/dist/types/src/errors.d.ts.map +1 -1
  29. package/dist/types/src/index.d.ts +6 -3
  30. package/dist/types/src/index.d.ts.map +1 -1
  31. package/dist/types/src/json-path.d.ts +2 -2
  32. package/dist/types/src/json-path.d.ts.map +1 -1
  33. package/dist/types/src/testing.d.ts +4 -3
  34. package/dist/types/src/testing.d.ts.map +1 -1
  35. package/dist/types/tsconfig.tsbuildinfo +1 -1
  36. package/package.json +30 -11
  37. package/src/Performance.ts +45 -0
  38. package/src/RuntimeProvider.ts +35 -0
  39. package/src/ast.test.ts +34 -7
  40. package/src/ast.ts +84 -90
  41. package/src/atom-kvs.ts +35 -0
  42. package/src/dynamic-runtime.test.ts +465 -0
  43. package/src/dynamic-runtime.ts +195 -0
  44. package/src/errors.ts +69 -8
  45. package/src/index.ts +6 -3
  46. package/src/interrupt.test.ts +3 -1
  47. package/src/json-path.test.ts +7 -7
  48. package/src/json-path.ts +9 -12
  49. package/src/layers.test.ts +4 -2
  50. package/src/resource.ts +2 -2
  51. package/src/sanity.test.ts +6 -4
  52. package/src/testing.ts +6 -4
@@ -1,4 +1,7 @@
1
1
  import "@dxos/node-std/globals";
2
+ import {
3
+ __export
4
+ } from "./chunk-CGS2ULMK.mjs";
2
5
 
3
6
  // src/ast.ts
4
7
  import * as Function from "effect/Function";
@@ -8,65 +11,48 @@ import * as SchemaAST from "effect/SchemaAST";
8
11
  import { invariant } from "@dxos/invariant";
9
12
  import { isNonNullable } from "@dxos/util";
10
13
  var __dxlog_file = "/__w/dxos/dxos/packages/common/effect/src/ast.ts";
11
- var isTupleType2 = (node) => {
12
- return SchemaAST.isTupleType(node) && node.elements.length > 0;
13
- };
14
- var getSimpleType = (node) => {
15
- if (SchemaAST.isDeclaration(node) || SchemaAST.isObjectKeyword(node) || SchemaAST.isTypeLiteral(node) || // TODO(wittjosiah): Tuples are actually arrays.
16
- isTupleType2(node) || isDiscriminatedUnion(node)) {
17
- return "object";
18
- }
19
- if (SchemaAST.isStringKeyword(node)) {
20
- return "string";
21
- }
22
- if (SchemaAST.isNumberKeyword(node)) {
23
- return "number";
24
- }
25
- if (SchemaAST.isBooleanKeyword(node)) {
26
- return "boolean";
27
- }
28
- if (SchemaAST.isEnums(node)) {
29
- return "enum";
30
- }
31
- if (SchemaAST.isLiteral(node)) {
32
- return "literal";
33
- }
34
- };
35
- var isSimpleType = (node) => !!getSimpleType(node);
36
- (function(SimpleType2) {
37
- SimpleType2.getDefaultValue = (type) => {
38
- switch (type) {
39
- case "string": {
40
- return "";
14
+ var reduceRefinements = (type, refinements = []) => {
15
+ if (SchemaAST.isRefinement(type)) {
16
+ const filter = type.filter;
17
+ const nextType = {
18
+ ...type.from,
19
+ annotations: {
20
+ ...type.from.annotations,
21
+ ...type.annotations
41
22
  }
42
- case "number": {
43
- return 0;
44
- }
45
- case "boolean": {
46
- return false;
47
- }
48
- case "object": {
49
- return {};
50
- }
51
- default: {
52
- throw new Error(`Unsupported type for default value: ${type}`);
53
- }
54
- }
23
+ };
24
+ return reduceRefinements(nextType, [
25
+ ...refinements,
26
+ filter
27
+ ]);
28
+ }
29
+ return {
30
+ type,
31
+ refinements
55
32
  };
56
- })(SimpleType || (SimpleType = {}));
33
+ };
34
+ var getBaseType = (prop) => {
35
+ const encoded = SchemaAST.encodedBoundAST(prop.type);
36
+ const unwrapped = prop.isOptional && encoded._tag === "Union" ? encoded.types[0] : encoded;
37
+ return reduceRefinements(unwrapped);
38
+ };
39
+ var getProperties = (ast) => {
40
+ const properties = SchemaAST.getPropertySignatures(ast);
41
+ return properties.map((prop) => ({
42
+ ...getBaseType(prop),
43
+ name: prop.name,
44
+ isOptional: prop.isOptional,
45
+ isReadonly: prop.isReadonly
46
+ }));
47
+ };
57
48
  var VisitResult = /* @__PURE__ */ (function(VisitResult2) {
58
49
  VisitResult2[VisitResult2["CONTINUE"] = 0] = "CONTINUE";
59
50
  VisitResult2[VisitResult2["SKIP"] = 1] = "SKIP";
60
51
  VisitResult2[VisitResult2["EXIT"] = 2] = "EXIT";
61
52
  return VisitResult2;
62
53
  })({});
63
- var defaultTest = isSimpleType;
64
54
  var visit = (node, testOrVisitor, visitor) => {
65
- if (!visitor) {
66
- visitNode(node, defaultTest, testOrVisitor);
67
- } else {
68
- visitNode(node, testOrVisitor, visitor);
69
- }
55
+ visitNode(node, testOrVisitor, visitor);
70
56
  };
71
57
  var visitNode = (node, test, visitor, path = [], depth = 0) => {
72
58
  const $result = test?.(node, path, depth);
@@ -156,7 +142,7 @@ var findProperty = (schema, path) => {
156
142
  const typeNode = findNode(node, SchemaAST.isTypeLiteral);
157
143
  invariant(typeNode, void 0, {
158
144
  F: __dxlog_file,
159
- L: 265,
145
+ L: 237,
160
146
  S: void 0,
161
147
  A: [
162
148
  "typeNode",
@@ -176,10 +162,10 @@ var findProperty = (schema, path) => {
176
162
  return getProp(schema.ast, path.split("."));
177
163
  };
178
164
  var defaultAnnotations = {
179
- ["ObjectKeyword"]: SchemaAST.objectKeyword,
180
- ["StringKeyword"]: SchemaAST.stringKeyword,
181
- ["NumberKeyword"]: SchemaAST.numberKeyword,
182
- ["BooleanKeyword"]: SchemaAST.booleanKeyword
165
+ ObjectKeyword: SchemaAST.objectKeyword,
166
+ StringKeyword: SchemaAST.stringKeyword,
167
+ NumberKeyword: SchemaAST.numberKeyword,
168
+ BooleanKeyword: SchemaAST.booleanKeyword
183
169
  };
184
170
  var getAnnotation2 = (annotationId, noDefault = true) => (node) => {
185
171
  const id = Function.pipe(SchemaAST.getIdentifierAnnotation(node), Option.getOrUndefined);
@@ -210,13 +196,22 @@ var isOption = (node) => {
210
196
  var isLiteralUnion = (node) => {
211
197
  return SchemaAST.isUnion(node) && node.types.every(SchemaAST.isLiteral);
212
198
  };
199
+ var isArrayType = (node) => {
200
+ return SchemaAST.isTupleType(node) && node.elements.length === 0 && node.rest.length === 1;
201
+ };
202
+ var getArrayElementType = (node) => {
203
+ return isArrayType(node) ? node.rest.at(0)?.type : void 0;
204
+ };
205
+ var isTupleType2 = (node) => {
206
+ return SchemaAST.isTupleType(node) && node.elements.length > 0;
207
+ };
213
208
  var isDiscriminatedUnion = (node) => {
214
209
  return SchemaAST.isUnion(node) && !!getDiscriminatingProps(node)?.length;
215
210
  };
216
211
  var getDiscriminatingProps = (node) => {
217
212
  invariant(SchemaAST.isUnion(node), void 0, {
218
213
  F: __dxlog_file,
219
- L: 362,
214
+ L: 355,
220
215
  S: void 0,
221
216
  A: [
222
217
  "SchemaAST.isUnion(node)",
@@ -234,7 +229,7 @@ var getDiscriminatingProps = (node) => {
234
229
  var getDiscriminatedType = (node, value = {}) => {
235
230
  invariant(SchemaAST.isUnion(node), void 0, {
236
231
  F: __dxlog_file,
237
- L: 386,
232
+ L: 379,
238
233
  S: void 0,
239
234
  A: [
240
235
  "SchemaAST.isUnion(node)",
@@ -243,7 +238,7 @@ var getDiscriminatedType = (node, value = {}) => {
243
238
  });
244
239
  invariant(value, void 0, {
245
240
  F: __dxlog_file,
246
- L: 387,
241
+ L: 380,
247
242
  S: void 0,
248
243
  A: [
249
244
  "value",
@@ -258,7 +253,7 @@ var getDiscriminatedType = (node, value = {}) => {
258
253
  const match = SchemaAST.getPropertySignatures(type).filter((prop) => props?.includes(prop.name.toString())).every((prop) => {
259
254
  invariant(SchemaAST.isLiteral(prop.type), void 0, {
260
255
  F: __dxlog_file,
261
- L: 398,
256
+ L: 391,
262
257
  S: void 0,
263
258
  A: [
264
259
  "SchemaAST.isLiteral(prop.type)",
@@ -276,7 +271,7 @@ var getDiscriminatedType = (node, value = {}) => {
276
271
  const literal = SchemaAST.getPropertySignatures(type).find((p) => p.name.toString() === prop);
277
272
  invariant(SchemaAST.isLiteral(literal.type), void 0, {
278
273
  F: __dxlog_file,
279
- L: 416,
274
+ L: 409,
280
275
  S: void 0,
281
276
  A: [
282
277
  "SchemaAST.isLiteral(literal.type)",
@@ -293,6 +288,10 @@ var getDiscriminatedType = (node, value = {}) => {
293
288
  const schema = Schema.Struct(fields);
294
289
  return schema.ast;
295
290
  };
291
+ var isNestedType = (node) => {
292
+ return SchemaAST.isDeclaration(node) || SchemaAST.isObjectKeyword(node) || SchemaAST.isTypeLiteral(node) || // TODO(wittjosiah): Tuples are actually arrays.
293
+ isTupleType2(node) || isDiscriminatedUnion(node);
294
+ };
296
295
  var mapAst = (ast, f) => {
297
296
  switch (ast._tag) {
298
297
  case "TypeLiteral": {
@@ -313,9 +312,6 @@ var mapAst = (ast, f) => {
313
312
  }
314
313
  }
315
314
  };
316
- var isArrayType = (node) => {
317
- return SchemaAST.isTupleType(node) || SchemaAST.isUnion(node) && node.types.some(isArrayType) && node.types.some(SchemaAST.isUndefinedKeyword) && node.types.length === 2;
318
- };
319
315
  var getIndexSignatures = (ast) => {
320
316
  const annotation = SchemaAST.getSurrogateAnnotation(ast);
321
317
  if (Option.isSome(annotation)) {
@@ -331,164 +327,64 @@ var getIndexSignatures = (ast) => {
331
327
  }
332
328
  return [];
333
329
  };
334
- var SimpleType;
335
-
336
- // src/json-path.ts
337
- import * as Option2 from "effect/Option";
338
- import * as Schema2 from "effect/Schema";
339
- import { JSONPath } from "jsonpath-plus";
340
- import { invariant as invariant2 } from "@dxos/invariant";
341
- import { getDeep, setDeep } from "@dxos/util";
342
- var __dxlog_file2 = "/__w/dxos/dxos/packages/common/effect/src/json-path.ts";
343
- var PATH_REGEX = /^($|[a-zA-Z_$][\w$]*(?:\.[a-zA-Z_$][\w$]*|\[\d+\](?:\.)?)*$)/;
344
- var PROP_REGEX = /^\w+$/;
345
- var JsonPath = Schema2.String.pipe(Schema2.pattern(PATH_REGEX)).annotations({
346
- title: "JSON path",
347
- description: "JSON path to a property"
348
- });
349
- var JsonProp = Schema2.NonEmptyString.pipe(Schema2.pattern(PROP_REGEX, {
350
- message: () => "Property name must contain only letters, numbers, and underscores"
351
- }));
352
- var isJsonPath = (value) => {
353
- return Option2.isSome(Schema2.validateOption(JsonPath)(value));
354
- };
355
- var createJsonPath = (path) => {
356
- const candidatePath = path.map((p, i) => {
357
- if (typeof p === "number") {
358
- return `[${p}]`;
359
- } else {
360
- return i === 0 ? p : `.${p}`;
361
- }
362
- }).join("");
363
- invariant2(isJsonPath(candidatePath), `Invalid JsonPath: ${candidatePath}`, {
364
- F: __dxlog_file2,
365
- L: 69,
366
- S: void 0,
367
- A: [
368
- "isJsonPath(candidatePath)",
369
- "`Invalid JsonPath: ${candidatePath}`"
370
- ]
371
- });
372
- return candidatePath;
373
- };
374
- var fromEffectValidationPath = (effectPath) => {
375
- const jsonPath = effectPath.replace(/\.\[(\d+)\]/g, "[$1]");
376
- invariant2(isJsonPath(jsonPath), `Invalid JsonPath: ${jsonPath}`, {
377
- F: __dxlog_file2,
378
- L: 80,
379
- S: void 0,
380
- A: [
381
- "isJsonPath(jsonPath)",
382
- "`Invalid JsonPath: ${jsonPath}`"
383
- ]
384
- });
385
- return jsonPath;
386
- };
387
- var splitJsonPath = (path) => {
388
- if (!isJsonPath(path)) {
389
- return [];
390
- }
391
- return path.match(/[a-zA-Z_$][\w$]*|\[\d+\]/g)?.map((part) => part.startsWith("[") ? part.replace(/[[\]]/g, "") : part) ?? [];
392
- };
393
- var getField = (object, path) => {
394
- return JSONPath({
395
- path,
396
- json: object
397
- })[0];
398
- };
399
- var getValue = (obj, path) => {
400
- return getDeep(obj, splitJsonPath(path).map((p) => p.replace(/[[\]]/g, "")));
401
- };
402
- var setValue = (obj, path, value) => {
403
- return setDeep(obj, splitJsonPath(path).map((p) => p.replace(/[[\]]/g, "")), value);
404
- };
405
330
 
406
- // src/url.ts
407
- import * as Function2 from "effect/Function";
408
- import * as Option3 from "effect/Option";
409
- import * as SchemaAST2 from "effect/SchemaAST";
410
- import { decamelize } from "@dxos/util";
411
- var ParamKeyAnnotationId = Symbol.for("@dxos/schema/annotation/ParamKey");
412
- var getParamKeyAnnotation = SchemaAST2.getAnnotation(ParamKeyAnnotationId);
413
- var ParamKeyAnnotation = (value) => (self) => self.annotations({
414
- [ParamKeyAnnotationId]: value
415
- });
416
- var UrlParser = class {
417
- _schema;
418
- constructor(_schema) {
419
- this._schema = _schema;
420
- }
421
- /**
422
- * Parse URL params.
423
- */
424
- parse(_url) {
425
- const url = new URL(_url);
426
- return Object.entries(this._schema.fields).reduce((params, [key, type]) => {
427
- let value = url.searchParams.get(decamelize(key));
428
- if (value == null) {
429
- value = url.searchParams.get(key);
430
- }
431
- if (value != null) {
432
- if (SchemaAST2.isNumberKeyword(type.ast)) {
433
- params[key] = parseInt(value);
434
- } else if (SchemaAST2.isBooleanKeyword(type.ast)) {
435
- params[key] = value === "true" || value === "1";
436
- } else {
437
- params[key] = value;
438
- }
439
- }
440
- return params;
441
- }, {});
442
- }
443
- /**
444
- * Return URL with encoded params.
445
- */
446
- create(_url, params) {
447
- const url = new URL(_url);
448
- Object.entries(params).forEach(([key, value]) => {
449
- if (value !== void 0) {
450
- const field = this._schema.fields[key];
451
- if (field) {
452
- const { key: serializedKey } = Function2.pipe(getParamKeyAnnotation(field.ast), Option3.getOrElse(() => ({
453
- key: decamelize(key)
454
- })));
455
- url.searchParams.set(serializedKey, String(value));
456
- }
457
- }
458
- });
459
- return url;
460
- }
331
+ // src/atom-kvs.ts
332
+ import { Atom } from "@effect-atom/atom-react";
333
+ import * as BrowserKeyValueStore from "@effect/platform-browser/BrowserKeyValueStore";
334
+ var defaultRuntime = Atom.runtime(BrowserKeyValueStore.layerLocalStorage);
335
+ var createKvsStore = (options) => {
336
+ const runtime2 = options.runtime ?? defaultRuntime;
337
+ return Atom.kvs({
338
+ runtime: runtime2,
339
+ key: options.key,
340
+ schema: options.schema,
341
+ defaultValue: options.defaultValue
342
+ }).pipe(Atom.keepAlive);
461
343
  };
462
344
 
463
345
  // src/context.ts
464
346
  import * as Effect from "effect/Effect";
465
347
  import { Context } from "@dxos/context";
466
- var __dxlog_file3 = "/__w/dxos/dxos/packages/common/effect/src/context.ts";
348
+ var __dxlog_file2 = "/__w/dxos/dxos/packages/common/effect/src/context.ts";
467
349
  var contextFromScope = () => Effect.gen(function* () {
468
350
  const ctx = new Context(void 0, {
469
- F: __dxlog_file3,
351
+ F: __dxlog_file2,
470
352
  L: 13
471
353
  });
472
354
  yield* Effect.addFinalizer(() => Effect.promise(() => ctx.dispose()));
473
355
  return ctx;
474
356
  });
475
357
 
358
+ // src/dynamic-runtime.ts
359
+ var dynamic_runtime_exports = {};
360
+ __export(dynamic_runtime_exports, {
361
+ make: () => make
362
+ });
363
+ import * as Context2 from "effect/Context";
364
+ import * as Effect3 from "effect/Effect";
365
+ import * as Exit2 from "effect/Exit";
366
+ import * as Option3 from "effect/Option";
367
+ import * as Runtime2 from "effect/Runtime";
368
+
476
369
  // src/errors.ts
477
370
  import * as Cause from "effect/Cause";
478
371
  import * as Chunk from "effect/Chunk";
479
372
  import * as Effect2 from "effect/Effect";
480
373
  import * as Exit from "effect/Exit";
481
374
  import * as GlobalValue from "effect/GlobalValue";
482
- import * as Option4 from "effect/Option";
483
- var spanSymbol = Symbol.for("effect/SpanAnnotation");
484
- var originalSymbol = Symbol.for("effect/OriginalAnnotation");
375
+ import * as Option2 from "effect/Option";
376
+ import * as Runtime from "effect/Runtime";
377
+ var spanSymbol = /* @__PURE__ */ Symbol.for("effect/SpanAnnotation");
485
378
  var spanToTrace = GlobalValue.globalValue("effect/Tracer/spanToTrace", () => /* @__PURE__ */ new WeakMap());
486
379
  var locationRegex = /\((.*)\)/g;
487
380
  var prettyErrorStack = (error, appendStacks = []) => {
381
+ if (typeof error !== "object" || error === null) {
382
+ return error;
383
+ }
488
384
  const span = error[spanSymbol];
489
385
  const lines = typeof error.stack === "string" ? error.stack.split("\n") : [];
490
386
  const out = [];
491
- let atStack = false;
387
+ let atStack = false, inCore = false, passedScheduler = false;
492
388
  for (let i = 0; i < lines.length; i++) {
493
389
  if (!atStack && !lines[i].startsWith(" at ")) {
494
390
  out.push(lines[i]);
@@ -505,6 +401,26 @@ var prettyErrorStack = (error, appendStacks = []) => {
505
401
  if (lines[i].includes("effect_internal_function")) {
506
402
  break;
507
403
  }
404
+ const filename = lines[i].match(/\/([a-zA-Z0-9_\-.]+):\d+:\d+\)$/)?.[1];
405
+ if (!inCore && [
406
+ "core-effect.ts"
407
+ ].includes(filename)) {
408
+ inCore = true;
409
+ }
410
+ if (inCore && !passedScheduler && [
411
+ "Scheduler.ts"
412
+ ].includes(filename)) {
413
+ passedScheduler = true;
414
+ continue;
415
+ }
416
+ if (passedScheduler && ![
417
+ "Scheduler.ts"
418
+ ].includes(filename)) {
419
+ inCore = false;
420
+ }
421
+ if (inCore) {
422
+ continue;
423
+ }
508
424
  out.push(lines[i].replace(/at .*effect_instruction_i.*\((.*)\)/, "at $1").replace(/EffectPrimitive\.\w+/, "<anonymous>").replace(/at Arguments\./, "at "));
509
425
  }
510
426
  if (span) {
@@ -530,14 +446,12 @@ var prettyErrorStack = (error, appendStacks = []) => {
530
446
  } else {
531
447
  out.push(` at ${current.name}`);
532
448
  }
533
- current = Option4.getOrUndefined(current.parent);
449
+ current = Option2.getOrUndefined(current.parent);
534
450
  i++;
535
451
  }
536
452
  }
537
453
  out.push(...appendStacks);
538
- if (error[originalSymbol]) {
539
- error = error[originalSymbol];
540
- }
454
+ error = Cause.originalError(error);
541
455
  if (error.cause) {
542
456
  error.cause = prettyErrorStack(error.cause);
543
457
  }
@@ -560,8 +474,8 @@ var causeToError = (cause) => {
560
474
  ...Chunk.toArray(Cause.defects(cause))
561
475
  ];
562
476
  const getStackFrames = () => {
563
- const o = {};
564
- Error.captureStackTrace(o, getStackFrames);
477
+ const o = new Error();
478
+ Error.captureStackTrace(o, causeToError);
565
479
  return o.stack.split("\n").slice(1);
566
480
  };
567
481
  const stackFrames = getStackFrames();
@@ -576,15 +490,30 @@ var causeToError = (cause) => {
576
490
  var throwCause = (cause) => {
577
491
  throw causeToError(cause);
578
492
  };
579
- var unwrapExit = (exit) => {
580
- if (Exit.isSuccess(exit)) {
581
- return exit.value;
493
+ var unwrapExit = (exit2) => {
494
+ if (Exit.isSuccess(exit2)) {
495
+ return exit2.value;
582
496
  }
583
- return throwCause(exit.cause);
497
+ return throwCause(exit2.cause);
584
498
  };
585
499
  var runAndForwardErrors = async (effect, options) => {
586
- const exit = await Effect2.runPromiseExit(effect, options);
587
- return unwrapExit(exit);
500
+ const exit2 = await Effect2.runPromiseExit(effect, options);
501
+ return unwrapExit(exit2);
502
+ };
503
+ var runInRuntime = (...args) => {
504
+ if (args.length === 1) {
505
+ const [runtime2] = args;
506
+ return async (effect, options) => {
507
+ const exit2 = await Runtime.runPromiseExit(runtime2, effect, options);
508
+ return unwrapExit(exit2);
509
+ };
510
+ } else {
511
+ const [runtime2, effect, options] = args;
512
+ return (async () => {
513
+ const exit2 = await Runtime.runPromiseExit(runtime2, effect, options);
514
+ return unwrapExit(exit2);
515
+ })();
516
+ }
588
517
  };
589
518
  var promiseWithCauseCapture = (evaluate) => Effect2.promise(async (signal) => {
590
519
  try {
@@ -595,83 +524,311 @@ var promiseWithCauseCapture = (evaluate) => Effect2.promise(async (signal) => {
595
524
  }
596
525
  }).pipe(Effect2.flatten);
597
526
 
598
- // src/testing.ts
599
- import * as Context2 from "effect/Context";
600
- import * as Effect3 from "effect/Effect";
601
- (function(TestHelpers2) {
602
- TestHelpers2.runIf = (condition) => (effect, ctx) => Effect3.gen(function* () {
603
- if (!condition) {
604
- ctx.skip();
605
- } else {
606
- return yield* effect;
527
+ // src/dynamic-runtime.ts
528
+ var validateTags = (context, tags) => Effect3.gen(function* () {
529
+ const missingTags = [];
530
+ for (const tag of tags) {
531
+ const option = Context2.getOption(context, tag);
532
+ if (Option3.isNone(option)) {
533
+ missingTags.push(tag.key);
607
534
  }
608
- });
609
- TestHelpers2.skipIf = (condition) => (effect, ctx) => Effect3.gen(function* () {
610
- if (condition) {
611
- ctx.skip();
612
- } else {
613
- return yield* effect;
535
+ }
536
+ if (missingTags.length > 0) {
537
+ return yield* Effect3.die(new Error(`Missing required tags in runtime: ${missingTags.join(", ")}`));
538
+ }
539
+ });
540
+ function make(managedRuntime, tags) {
541
+ const managedRuntimeAny = managedRuntime;
542
+ let cachedRuntime;
543
+ let validatedRuntimePromise;
544
+ const getValidatedRuntimeAsync = async () => {
545
+ if (!validatedRuntimePromise) {
546
+ validatedRuntimePromise = managedRuntimeAny.runPromise(Effect3.gen(function* () {
547
+ const rt = yield* managedRuntimeAny.runtimeEffect;
548
+ yield* validateTags(rt.context, tags);
549
+ return rt;
550
+ }));
614
551
  }
615
- });
616
- TestHelpers2.taggedTest = (tag) => (effect, ctx) => Effect3.gen(function* () {
617
- if (!process.env.DX_TEST_TAGS?.includes(tag)) {
618
- ctx.skip();
552
+ return validatedRuntimePromise;
553
+ };
554
+ const getValidatedRuntime = () => {
555
+ const validationExit = managedRuntimeAny.runSyncExit(Effect3.gen(function* () {
556
+ const rt = yield* managedRuntimeAny.runtimeEffect;
557
+ yield* validateTags(rt.context, tags);
558
+ return rt;
559
+ }));
560
+ return unwrapExit(validationExit);
561
+ };
562
+ return {
563
+ managedRuntime: managedRuntimeAny,
564
+ runPromise: async (effect) => {
565
+ const runtime2 = await getValidatedRuntimeAsync();
566
+ return Runtime2.runPromise(runtime2)(effect);
567
+ },
568
+ runSync: (effect) => {
569
+ const runtime2 = getValidatedRuntime();
570
+ return Runtime2.runSync(runtime2)(effect);
571
+ },
572
+ runSyncExit: (effect) => {
573
+ const validationExit = managedRuntimeAny.runSyncExit(Effect3.gen(function* () {
574
+ const rt = yield* managedRuntimeAny.runtimeEffect;
575
+ yield* validateTags(rt.context, tags);
576
+ return rt;
577
+ }));
578
+ if (Exit2.isSuccess(validationExit)) {
579
+ const runtime2 = validationExit.value;
580
+ return Runtime2.runSyncExit(runtime2)(effect);
581
+ }
582
+ return validationExit;
583
+ },
584
+ runPromiseExit: async (effect) => {
585
+ try {
586
+ const runtime2 = await getValidatedRuntimeAsync();
587
+ return Runtime2.runPromiseExit(runtime2)(effect);
588
+ } catch (error) {
589
+ return Exit2.die(error);
590
+ }
591
+ },
592
+ runFork: (effect) => {
593
+ const runtime2 = getValidatedRuntime();
594
+ return Runtime2.runFork(runtime2)(effect);
595
+ },
596
+ runtimeEffect: Effect3.gen(function* () {
597
+ if (cachedRuntime) {
598
+ return cachedRuntime;
599
+ }
600
+ const rt = yield* managedRuntimeAny.runtimeEffect;
601
+ yield* validateTags(rt.context, tags);
602
+ const runtime2 = rt;
603
+ cachedRuntime = runtime2;
604
+ return runtime2;
605
+ }).pipe(Effect3.catchAll(() => (
606
+ // This should never happen since validateTags uses Effect.die
607
+ Effect3.die(new Error("Unexpected error in runtimeEffect validation"))
608
+ ))),
609
+ dispose: async () => {
610
+ await managedRuntimeAny.dispose();
611
+ }
612
+ };
613
+ }
614
+
615
+ // src/json-path.ts
616
+ import * as Option4 from "effect/Option";
617
+ import * as Schema2 from "effect/Schema";
618
+ import { JSONPath } from "jsonpath-plus";
619
+ import { invariant as invariant2 } from "@dxos/invariant";
620
+ import { getDeep, setDeep } from "@dxos/util";
621
+ var __dxlog_file3 = "/__w/dxos/dxos/packages/common/effect/src/json-path.ts";
622
+ var PATH_REGEX = /^($|[a-zA-Z_$][\w$]*(?:\.[a-zA-Z_$][\w$]*|\[\d+\](?:\.)?)*$)/;
623
+ var PROP_REGEX = /^\w+$/;
624
+ var JsonPath = Schema2.String.pipe(Schema2.pattern(PATH_REGEX)).annotations({
625
+ title: "JSON path",
626
+ description: "JSON path to a property"
627
+ });
628
+ var JsonProp = Schema2.NonEmptyString.pipe(Schema2.pattern(PROP_REGEX, {
629
+ message: () => "Property name must contain only letters, numbers, and underscores"
630
+ }));
631
+ var isJsonPath = (value) => {
632
+ return Option4.isSome(Schema2.validateOption(JsonPath)(value));
633
+ };
634
+ var createJsonPath = (path) => {
635
+ const candidatePath = path.map((p, i) => {
636
+ if (typeof p === "number") {
637
+ return `[${p}]`;
619
638
  } else {
620
- return yield* effect;
639
+ return i === 0 ? p : `.${p}`;
621
640
  }
641
+ }).join("");
642
+ invariant2(isJsonPath(candidatePath), `Invalid JsonPath: ${candidatePath}`, {
643
+ F: __dxlog_file3,
644
+ L: 69,
645
+ S: void 0,
646
+ A: [
647
+ "isJsonPath(candidatePath)",
648
+ "`Invalid JsonPath: ${candidatePath}`"
649
+ ]
622
650
  });
623
- TestHelpers2.provideTestContext = (effect, ctx) => Effect3.provideService(effect, TestContextService, ctx);
624
- })(TestHelpers || (TestHelpers = {}));
625
- var TestContextService = class extends Context2.Tag("@dxos/effect/TestContextService")() {
651
+ return candidatePath;
652
+ };
653
+ var fromEffectValidationPath = (effectPath) => {
654
+ const jsonPath = effectPath.replace(/\.\[(\d+)\]/g, "[$1]");
655
+ invariant2(isJsonPath(jsonPath), `Invalid JsonPath: ${jsonPath}`, {
656
+ F: __dxlog_file3,
657
+ L: 80,
658
+ S: void 0,
659
+ A: [
660
+ "isJsonPath(jsonPath)",
661
+ "`Invalid JsonPath: ${jsonPath}`"
662
+ ]
663
+ });
664
+ return jsonPath;
665
+ };
666
+ var splitJsonPath = (path) => {
667
+ if (!isJsonPath(path)) {
668
+ return [];
669
+ }
670
+ return path.match(/[a-zA-Z_$][\w$]*|\[\d+\]/g)?.map((part) => part.replace(/[[\]]/g, "")).map((part) => {
671
+ const parsed = Number.parseInt(part, 10);
672
+ return Number.isNaN(parsed) ? part : parsed;
673
+ }) ?? [];
674
+ };
675
+ var getField = (object, path) => {
676
+ return JSONPath({
677
+ path,
678
+ json: object
679
+ })[0];
680
+ };
681
+ var getValue = (obj, path) => {
682
+ return getDeep(obj, splitJsonPath(path));
683
+ };
684
+ var setValue = (obj, path, value) => {
685
+ return setDeep(obj, splitJsonPath(path), value);
626
686
  };
627
- var TestHelpers;
628
687
 
629
688
  // src/resource.ts
630
689
  import * as Effect4 from "effect/Effect";
631
690
  var acquireReleaseResource = (getResource) => Effect4.acquireRelease(Effect4.gen(function* () {
632
691
  const resource = getResource();
633
692
  yield* Effect4.promise(async () => {
634
- resource.open?.();
693
+ await resource.open?.();
635
694
  return void 0;
636
695
  });
637
696
  return resource;
638
697
  }), (resource) => Effect4.promise(async () => {
639
- resource.close?.();
698
+ await resource.close?.();
640
699
  return void 0;
641
700
  }));
701
+
702
+ // src/url.ts
703
+ import * as Function2 from "effect/Function";
704
+ import * as Option5 from "effect/Option";
705
+ import * as SchemaAST2 from "effect/SchemaAST";
706
+ import { decamelize } from "@dxos/util";
707
+ var ParamKeyAnnotationId = /* @__PURE__ */ Symbol.for("@dxos/schema/annotation/ParamKey");
708
+ var getParamKeyAnnotation = SchemaAST2.getAnnotation(ParamKeyAnnotationId);
709
+ var ParamKeyAnnotation = (value) => (self) => self.annotations({
710
+ [ParamKeyAnnotationId]: value
711
+ });
712
+ var UrlParser = class {
713
+ _schema;
714
+ constructor(_schema) {
715
+ this._schema = _schema;
716
+ }
717
+ /**
718
+ * Parse URL params.
719
+ */
720
+ parse(_url) {
721
+ const url = new URL(_url);
722
+ return Object.entries(this._schema.fields).reduce((params, [key, type]) => {
723
+ let value = url.searchParams.get(decamelize(key));
724
+ if (value == null) {
725
+ value = url.searchParams.get(key);
726
+ }
727
+ if (value != null) {
728
+ if (SchemaAST2.isNumberKeyword(type.ast)) {
729
+ params[key] = parseInt(value);
730
+ } else if (SchemaAST2.isBooleanKeyword(type.ast)) {
731
+ params[key] = value === "true" || value === "1";
732
+ } else {
733
+ params[key] = value;
734
+ }
735
+ }
736
+ return params;
737
+ }, {});
738
+ }
739
+ /**
740
+ * Return URL with encoded params.
741
+ */
742
+ create(_url, params) {
743
+ const url = new URL(_url);
744
+ Object.entries(params).forEach(([key, value]) => {
745
+ if (value !== void 0) {
746
+ const field = this._schema.fields[key];
747
+ if (field) {
748
+ const { key: serializedKey } = Function2.pipe(getParamKeyAnnotation(field.ast), Option5.getOrElse(() => ({
749
+ key: decamelize(key)
750
+ })));
751
+ url.searchParams.set(serializedKey, String(value));
752
+ }
753
+ }
754
+ });
755
+ return url;
756
+ }
757
+ };
758
+
759
+ // src/RuntimeProvider.ts
760
+ var RuntimeProvider_exports = {};
761
+ __export(RuntimeProvider_exports, {
762
+ currentRuntime: () => currentRuntime,
763
+ provide: () => provide2,
764
+ runPromise: () => runPromise2
765
+ });
766
+ import * as Effect5 from "effect/Effect";
767
+ import * as Runtime3 from "effect/Runtime";
768
+ var currentRuntime = () => Effect5.runtime().pipe(Effect5.map(Effect5.succeed));
769
+ var runPromise2 = (provider) => async (effect) => {
770
+ const runtime2 = await runAndForwardErrors(provider);
771
+ return unwrapExit(await effect.pipe(Runtime3.runPromiseExit(runtime2)));
772
+ };
773
+ var provide2 = (runtimeProvider) => (effect) => Effect5.flatMap(runtimeProvider, (runtime2) => Effect5.provide(effect, runtime2));
774
+
775
+ // src/Performance.ts
776
+ var Performance_exports = {};
777
+ __export(Performance_exports, {
778
+ addTrackEntry: () => addTrackEntry
779
+ });
780
+ import * as Effect6 from "effect/Effect";
781
+ var addTrackEntry = (options) => (effect) => Effect6.gen(function* () {
782
+ const start = performance.now();
783
+ const exit2 = yield* Effect6.exit(effect);
784
+ const resolvedOptions = typeof options === "function" ? options(exit2) : options;
785
+ performance.measure(resolvedOptions.name, {
786
+ start,
787
+ detail: {
788
+ ...resolvedOptions.detail,
789
+ devtools: resolvedOptions.devtools
790
+ }
791
+ });
792
+ return yield* exit2;
793
+ });
642
794
  export {
795
+ dynamic_runtime_exports as DynamicRuntime,
643
796
  JsonPath,
644
797
  JsonProp,
645
798
  ParamKeyAnnotation,
646
- SimpleType,
647
- TestContextService,
648
- TestHelpers,
799
+ Performance_exports as Performance,
800
+ RuntimeProvider_exports as RuntimeProvider,
649
801
  UrlParser,
650
802
  VisitResult,
651
803
  acquireReleaseResource,
652
804
  causeToError,
653
805
  contextFromScope,
654
806
  createJsonPath,
807
+ createKvsStore,
655
808
  findAnnotation,
656
809
  findNode,
657
810
  findProperty,
658
811
  fromEffectValidationPath,
659
812
  getAnnotation2 as getAnnotation,
813
+ getArrayElementType,
814
+ getBaseType,
660
815
  getDiscriminatedType,
661
816
  getDiscriminatingProps,
662
817
  getField,
663
818
  getParamKeyAnnotation,
664
- getSimpleType,
819
+ getProperties,
665
820
  getValue,
666
821
  isArrayType,
667
822
  isDiscriminatedUnion,
668
823
  isJsonPath,
669
824
  isLiteralUnion,
825
+ isNestedType,
670
826
  isOption,
671
- isSimpleType,
827
+ isTupleType2 as isTupleType,
672
828
  mapAst,
673
829
  promiseWithCauseCapture,
674
830
  runAndForwardErrors,
831
+ runInRuntime,
675
832
  setValue,
676
833
  splitJsonPath,
677
834
  throwCause,