@livestore/utils 0.4.0-dev.1 → 0.4.0-dev.11

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 (102) hide show
  1. package/dist/.tsbuildinfo.json +1 -1
  2. package/dist/NoopTracer.d.ts.map +1 -1
  3. package/dist/NoopTracer.js +1 -0
  4. package/dist/NoopTracer.js.map +1 -1
  5. package/dist/effect/Effect.d.ts +9 -3
  6. package/dist/effect/Effect.d.ts.map +1 -1
  7. package/dist/effect/Effect.js +4 -2
  8. package/dist/effect/Effect.js.map +1 -1
  9. package/dist/effect/Error.d.ts +1 -1
  10. package/dist/effect/Error.js.map +1 -1
  11. package/dist/effect/Logger.d.ts +4 -1
  12. package/dist/effect/Logger.d.ts.map +1 -1
  13. package/dist/effect/Logger.js +12 -3
  14. package/dist/effect/Logger.js.map +1 -1
  15. package/dist/effect/OtelTracer.d.ts +5 -0
  16. package/dist/effect/OtelTracer.d.ts.map +1 -0
  17. package/dist/effect/OtelTracer.js +8 -0
  18. package/dist/effect/OtelTracer.js.map +1 -0
  19. package/dist/effect/RpcClient.d.ts +32 -0
  20. package/dist/effect/RpcClient.d.ts.map +1 -0
  21. package/dist/effect/RpcClient.js +149 -0
  22. package/dist/effect/RpcClient.js.map +1 -0
  23. package/dist/effect/Schema/index.d.ts +2 -2
  24. package/dist/effect/Schema/index.d.ts.map +1 -1
  25. package/dist/effect/Schema/index.js +12 -2
  26. package/dist/effect/Schema/index.js.map +1 -1
  27. package/dist/effect/Stream.d.ts +73 -2
  28. package/dist/effect/Stream.d.ts.map +1 -1
  29. package/dist/effect/Stream.js +68 -1
  30. package/dist/effect/Stream.js.map +1 -1
  31. package/dist/effect/Stream.test.d.ts +2 -0
  32. package/dist/effect/Stream.test.d.ts.map +1 -0
  33. package/dist/effect/Stream.test.js +84 -0
  34. package/dist/effect/Stream.test.js.map +1 -0
  35. package/dist/effect/SubscriptionRef.d.ts +2 -2
  36. package/dist/effect/SubscriptionRef.d.ts.map +1 -1
  37. package/dist/effect/SubscriptionRef.js +6 -1
  38. package/dist/effect/SubscriptionRef.js.map +1 -1
  39. package/dist/effect/WebChannel/common.d.ts +1 -1
  40. package/dist/effect/WebChannel/common.d.ts.map +1 -1
  41. package/dist/effect/WebSocket.js +1 -1
  42. package/dist/effect/WebSocket.js.map +1 -1
  43. package/dist/effect/index.d.ts +17 -11
  44. package/dist/effect/index.d.ts.map +1 -1
  45. package/dist/effect/index.js +20 -15
  46. package/dist/effect/index.js.map +1 -1
  47. package/dist/global.d.ts +1 -0
  48. package/dist/global.d.ts.map +1 -1
  49. package/dist/global.js.map +1 -1
  50. package/dist/misc.js +1 -1
  51. package/dist/misc.js.map +1 -1
  52. package/dist/mod.d.ts +2 -0
  53. package/dist/mod.d.ts.map +1 -1
  54. package/dist/mod.js +4 -0
  55. package/dist/mod.js.map +1 -1
  56. package/dist/node/ChildProcessRunner/ChildProcessRunner.d.ts.map +1 -1
  57. package/dist/node/ChildProcessRunner/ChildProcessRunner.js +66 -10
  58. package/dist/node/ChildProcessRunner/ChildProcessRunner.js.map +1 -1
  59. package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/ChildProcessRunner.test.js +177 -3
  60. package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/ChildProcessRunner.test.js.map +1 -1
  61. package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/schema.d.ts +10 -1
  62. package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/schema.d.ts.map +1 -1
  63. package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/schema.js +7 -1
  64. package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/schema.js.map +1 -1
  65. package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/serializedWorker.js +13 -3
  66. package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/serializedWorker.js.map +1 -1
  67. package/dist/node/ChildProcessRunner/ChildProcessWorker.d.ts +16 -0
  68. package/dist/node/ChildProcessRunner/ChildProcessWorker.d.ts.map +1 -1
  69. package/dist/node/ChildProcessRunner/ChildProcessWorker.js +98 -2
  70. package/dist/node/ChildProcessRunner/ChildProcessWorker.js.map +1 -1
  71. package/dist/node/mod.d.ts +7 -1
  72. package/dist/node/mod.d.ts.map +1 -1
  73. package/dist/node/mod.js +10 -2
  74. package/dist/node/mod.js.map +1 -1
  75. package/package.json +42 -41
  76. package/src/NoopTracer.ts +1 -0
  77. package/src/effect/Effect.ts +31 -4
  78. package/src/effect/Error.ts +1 -1
  79. package/src/effect/Logger.ts +14 -4
  80. package/src/effect/OtelTracer.ts +11 -0
  81. package/src/effect/RpcClient.ts +212 -0
  82. package/src/effect/Schema/index.ts +17 -3
  83. package/src/effect/Stream.test.ts +127 -0
  84. package/src/effect/Stream.ts +111 -2
  85. package/src/effect/SubscriptionRef.ts +14 -2
  86. package/src/effect/WebChannel/common.ts +1 -1
  87. package/src/effect/WebSocket.ts +1 -1
  88. package/src/effect/index.ts +40 -14
  89. package/src/global.ts +1 -0
  90. package/src/misc.ts +1 -1
  91. package/src/mod.ts +9 -0
  92. package/src/node/ChildProcessRunner/ChildProcessRunner.ts +71 -10
  93. package/src/node/ChildProcessRunner/ChildProcessRunnerTest/ChildProcessRunner.test.ts +258 -3
  94. package/src/node/ChildProcessRunner/ChildProcessRunnerTest/schema.ts +14 -1
  95. package/src/node/ChildProcessRunner/ChildProcessRunnerTest/serializedWorker.ts +16 -3
  96. package/src/node/ChildProcessRunner/ChildProcessWorker.ts +111 -3
  97. package/src/node/mod.ts +12 -5
  98. package/dist/effect/Schema/msgpack.d.ts +0 -3
  99. package/dist/effect/Schema/msgpack.d.ts.map +0 -1
  100. package/dist/effect/Schema/msgpack.js +0 -7
  101. package/dist/effect/Schema/msgpack.js.map +0 -1
  102. package/src/effect/Schema/msgpack.ts +0 -8
@@ -5,6 +5,12 @@ export * as SocketServer from '@effect/platform/SocketServer';
5
5
  export * as PlatformNode from '@effect/platform-node';
6
6
  export * as ChildProcessRunner from './ChildProcessRunner/ChildProcessRunner.ts';
7
7
  export * as ChildProcessWorker from './ChildProcessRunner/ChildProcessWorker.ts';
8
- export declare const getFreePort: Effect.Effect<number, UnknownError, never>;
8
+ export declare const getFreePort: Effect.Effect<number, UnknownError>;
9
9
  export declare const OtelLiveDummy: Layer.Layer<OtelTracer.OtelTracer>;
10
+ /**
11
+ * Layer that enables recursive file watching by combining the Node filesystem implementation with
12
+ * the Parcel-based watch backend. Mirrored from Effect’s platform-node Parcel watcher layer:
13
+ * https://github.com/Effect-TS/effect/blob/main/packages/platform-node/src/NodeFileSystem/ParcelWatcher.ts
14
+ */
15
+ export declare const NodeRecursiveWatchLayer: Layer.Layer<import("@effect/platform/FileSystem").FileSystem | import("@effect/platform/FileSystem").WatchBackend, never, never>;
10
16
  //# sourceMappingURL=mod.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/node/mod.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAEtC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAG7D,OAAO,KAAK,GAAG,MAAM,aAAa,CAAA;AAClC,OAAO,KAAK,YAAY,MAAM,+BAA+B,CAAA;AAC7D,OAAO,KAAK,YAAY,MAAM,uBAAuB,CAAA;AAErD,OAAO,KAAK,kBAAkB,MAAM,4CAA4C,CAAA;AAChF,OAAO,KAAK,kBAAkB,MAAM,4CAA4C,CAAA;AAOhF,eAAO,MAAM,WAAW,4CAuBtB,CAAA;AAEF,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU,CAQ3D,CAAA"}
1
+ {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/node/mod.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AACtC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAG7D,OAAO,KAAK,GAAG,MAAM,aAAa,CAAA;AAClC,OAAO,KAAK,YAAY,MAAM,+BAA+B,CAAA;AAC7D,OAAO,KAAK,YAAY,MAAM,uBAAuB,CAAA;AAErD,OAAO,KAAK,kBAAkB,MAAM,4CAA4C,CAAA;AAChF,OAAO,KAAK,kBAAkB,MAAM,4CAA4C,CAAA;AAOhF,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAuB1D,CAAA;AAEF,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU,CAQ3D,CAAA;AAEF;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,kIAAwE,CAAA"}
package/dist/node/mod.js CHANGED
@@ -1,4 +1,6 @@
1
1
  import * as http from 'node:http';
2
+ import * as PlatformNode from '@effect/platform-node';
3
+ import { layer as ParcelWatcherLayer } from '@effect/platform-node/NodeFileSystem/ParcelWatcher';
2
4
  import { Effect, Layer } from 'effect';
3
5
  import { OtelTracer, UnknownError } from "../effect/index.js";
4
6
  import { makeNoopTracer } from "../NoopTracer.js";
@@ -27,8 +29,8 @@ export const getFreePort = Effect.async((cb, signal) => {
27
29
  }
28
30
  });
29
31
  // Error handling in case the server encounters an error
30
- server.on('error', (err) => {
31
- server.close(() => cb(Effect.fail(new UnknownError({ cause: err }))));
32
+ server.on('error', (cause) => {
33
+ server.close(() => cb(Effect.fail(new UnknownError({ cause, payload: 'Failed to get a free port' }))));
32
34
  });
33
35
  });
34
36
  export const OtelLiveDummy = Layer.suspend(() => {
@@ -36,4 +38,10 @@ export const OtelLiveDummy = Layer.suspend(() => {
36
38
  const TracingLive = Layer.unwrapEffect(Effect.map(OtelTracer.make, Layer.setTracer)).pipe(Layer.provideMerge(OtelTracerLive));
37
39
  return TracingLive;
38
40
  });
41
+ /**
42
+ * Layer that enables recursive file watching by combining the Node filesystem implementation with
43
+ * the Parcel-based watch backend. Mirrored from Effect’s platform-node Parcel watcher layer:
44
+ * https://github.com/Effect-TS/effect/blob/main/packages/platform-node/src/NodeFileSystem/ParcelWatcher.ts
45
+ */
46
+ export const NodeRecursiveWatchLayer = Layer.mergeAll(PlatformNode.NodeFileSystem.layer, ParcelWatcherLayer);
39
47
  //# sourceMappingURL=mod.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mod.js","sourceRoot":"","sources":["../../src/node/mod.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AAEjC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAEtC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAEjD,OAAO,KAAK,GAAG,MAAM,aAAa,CAAA;AAClC,OAAO,KAAK,YAAY,MAAM,+BAA+B,CAAA;AAC7D,OAAO,KAAK,YAAY,MAAM,uBAAuB,CAAA;AAErD,OAAO,KAAK,kBAAkB,MAAM,4CAA4C,CAAA;AAChF,OAAO,KAAK,kBAAkB,MAAM,4CAA4C,CAAA;AAEhF,yCAAyC;AACzC,6EAA6E;AAE7E,6EAA6E;AAE7E,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAuB,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE;IAC3E,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,CAAA;IAElC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;QACpC,MAAM,CAAC,KAAK,EAAE,CAAA;IAChB,CAAC,CAAC,CAAA;IAEF,4CAA4C;IAC5C,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE;QACpB,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,CAAA;QAEhC,IAAI,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAC3C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAA;YACzB,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAC9C,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,EAAE,KAAK,EAAE,2BAA2B,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;QAC/F,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,wDAAwD;IACxD,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;QACzB,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;IACvE,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,aAAa,GAAuC,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;IAClF,MAAM,cAAc,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,EAAE,cAAc,EAAE,CAAC,CAAA;IAE7E,MAAM,WAAW,GAAG,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CACvF,KAAK,CAAC,YAAY,CAAC,cAAc,CAAC,CACnC,CAAA;IAED,OAAO,WAAW,CAAA;AACpB,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"mod.js","sourceRoot":"","sources":["../../src/node/mod.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,KAAK,YAAY,MAAM,uBAAuB,CAAA;AACrD,OAAO,EAAE,KAAK,IAAI,kBAAkB,EAAE,MAAM,oDAAoD,CAAA;AAChG,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AACtC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAEjD,OAAO,KAAK,GAAG,MAAM,aAAa,CAAA;AAClC,OAAO,KAAK,YAAY,MAAM,+BAA+B,CAAA;AAC7D,OAAO,KAAK,YAAY,MAAM,uBAAuB,CAAA;AAErD,OAAO,KAAK,kBAAkB,MAAM,4CAA4C,CAAA;AAChF,OAAO,KAAK,kBAAkB,MAAM,4CAA4C,CAAA;AAEhF,yCAAyC;AACzC,6EAA6E;AAE7E,6EAA6E;AAE7E,MAAM,CAAC,MAAM,WAAW,GAAwC,MAAM,CAAC,KAAK,CAAuB,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE;IAChH,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,CAAA;IAElC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;QACpC,MAAM,CAAC,KAAK,EAAE,CAAA;IAChB,CAAC,CAAC,CAAA;IAEF,4CAA4C;IAC5C,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE;QACpB,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,CAAA;QAEhC,IAAI,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAC3C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAA;YACzB,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAC9C,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,EAAE,KAAK,EAAE,2BAA2B,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;QAC/F,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,wDAAwD;IACxD,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;QAC3B,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,2BAA2B,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;IACxG,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,aAAa,GAAuC,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;IAClF,MAAM,cAAc,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,EAAE,cAAc,EAAE,CAAC,CAAA;IAE7E,MAAM,WAAW,GAAG,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CACvF,KAAK,CAAC,YAAY,CAAC,cAAc,CAAC,CACnC,CAAA;IAED,OAAO,WAAW,CAAA;AACpB,CAAC,CAAC,CAAA;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,cAAc,CAAC,KAAK,EAAE,kBAAkB,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "@livestore/utils",
3
- "version": "0.4.0-dev.1",
3
+ "version": "0.4.0-dev.11",
4
4
  "type": "module",
5
5
  "sideEffects": [
6
- "./src/global.ts"
6
+ "./src/global.ts",
7
+ "./dist/global.js"
7
8
  ],
8
9
  "exports": {
9
10
  ".": {
@@ -34,33 +35,35 @@
34
35
  }
35
36
  },
36
37
  "dependencies": {
38
+ "@effect/platform-node": "0.98.0",
37
39
  "@standard-schema/spec": "1.0.0",
38
- "msgpackr": "1.11.5",
39
40
  "nanoid": "5.1.5",
40
- "pretty-bytes": "7.0.0"
41
+ "pretty-bytes": "7.0.1"
41
42
  },
42
43
  "devDependencies": {
43
- "@effect/cli": "^0.69.0",
44
- "@effect/cluster": "^0.46.2",
45
- "@effect/experimental": "^0.54.3",
46
- "@effect/opentelemetry": "^0.56.1",
47
- "@effect/platform": "^0.90.0",
48
- "@effect/platform-browser": "^0.70.0",
49
- "@effect/platform-bun": "^0.77.0",
50
- "@effect/platform-node": "^0.94.1",
51
- "@effect/printer": "^0.45.0",
52
- "@effect/printer-ansi": "^0.45.0",
53
- "@effect/rpc": "^0.68.3",
54
- "@effect/sql": "^0.44.0",
55
- "@effect/typeclass": "^0.36.0",
56
- "@effect/vitest": "^0.25.0",
57
- "@opentelemetry/api": "^1.9.0",
44
+ "@effect/ai": "^0.29.0",
45
+ "@effect/cli": "^0.71.0",
46
+ "@effect/cluster": "^0.50.0",
47
+ "@effect/experimental": "^0.56.0",
48
+ "@effect/opentelemetry": "0.58.0",
49
+ "@effect/platform": "^0.92.0",
50
+ "@effect/platform-browser": "^0.72.0",
51
+ "@effect/platform-bun": "^0.81.0",
52
+ "@effect/platform-node": "^0.98.0",
53
+ "@effect/printer": "^0.46.0",
54
+ "@effect/printer-ansi": "^0.46.0",
55
+ "@effect/rpc": "^0.71.0",
56
+ "@effect/sql": "^0.46.0",
57
+ "@effect/typeclass": "^0.37.0",
58
+ "@effect/vitest": "^0.26.0",
59
+ "@effect/workflow": "^0.11.0",
60
+ "@opentelemetry/api": "1.9.0",
58
61
  "@opentelemetry/resources": "^2.0.1",
59
- "@types/bun": "^1.2.19",
62
+ "@types/bun": "^1.2.21",
60
63
  "@types/jsdom": "^21.1.7",
61
- "@types/node": "24.2.0",
62
- "@types/web": "^0.0.260",
63
- "effect": "^3.17.6",
64
+ "@types/node": "24.5.2",
65
+ "@types/web": "^0.0.264",
66
+ "effect": "3.18.0",
64
67
  "jsdom": "^26.1.0",
65
68
  "vitest": "3.2.4"
66
69
  },
@@ -71,28 +74,26 @@
71
74
  ],
72
75
  "license": "Apache-2.0",
73
76
  "peerDependencies": {
74
- "@effect/cli": "^0.69.0",
75
- "@effect/cluster": "^0.46.2",
76
- "@effect/experimental": "^0.54.3",
77
- "@effect/opentelemetry": "^0.56.1",
78
- "@effect/platform": "^0.90.0",
79
- "@effect/platform-browser": "^0.70.0",
80
- "@effect/platform-bun": "^0.77.0",
81
- "@effect/platform-node": "^0.94.1",
82
- "@effect/printer": "^0.45.0",
83
- "@effect/printer-ansi": "^0.45.0",
84
- "@effect/rpc": "^0.68.3",
85
- "@effect/sql": "^0.44.0",
86
- "@effect/typeclass": "^0.36.0",
77
+ "@effect/ai": "^0.29.0",
78
+ "@effect/cli": "^0.71.0",
79
+ "@effect/cluster": "^0.50.0",
80
+ "@effect/experimental": "^0.56.0",
81
+ "@effect/opentelemetry": "^0.58.0",
82
+ "@effect/platform": "^0.92.0",
83
+ "@effect/platform-browser": "^0.72.0",
84
+ "@effect/platform-bun": "^0.81.0",
85
+ "@effect/platform-node": "^0.98.0",
86
+ "@effect/printer": "^0.46.0",
87
+ "@effect/printer-ansi": "^0.46.0",
88
+ "@effect/rpc": "^0.71.0",
89
+ "@effect/sql": "^0.46.0",
90
+ "@effect/typeclass": "^0.37.0",
87
91
  "@opentelemetry/api": "^1.9.0",
88
92
  "@opentelemetry/resources": "^2.0.1",
89
- "effect": "^3.17.6"
93
+ "effect": "^3.18.0"
90
94
  },
91
95
  "publishConfig": {
92
- "access": "public",
93
- "sideEffects": [
94
- "./dist/global.js"
95
- ]
96
+ "access": "public"
96
97
  },
97
98
  "react-native": "./dist/index.js",
98
99
  "scripts": {
package/src/NoopTracer.ts CHANGED
@@ -9,6 +9,7 @@ export const makeNoopSpan = () => {
9
9
  setAttribute: () => null,
10
10
  setAttributes: () => null,
11
11
  addEvent: () => null,
12
+ addLink: () => null,
12
13
  setStatus: () => null,
13
14
  updateName: () => null,
14
15
  recordException: () => null,
@@ -1,9 +1,22 @@
1
1
  import * as OtelTracer from '@effect/opentelemetry/Tracer'
2
- import type { Context, Duration, Stream } from 'effect'
3
- import { Cause, Deferred, Effect, Fiber, FiberRef, HashSet, Logger, pipe, Scope } from 'effect'
2
+ import {
3
+ Cause,
4
+ type Context,
5
+ Deferred,
6
+ Duration,
7
+ Effect,
8
+ Fiber,
9
+ FiberRef,
10
+ HashSet,
11
+ Logger,
12
+ pipe,
13
+ Scope,
14
+ type Stream,
15
+ } from 'effect'
4
16
  import type { UnknownException } from 'effect/Cause'
5
17
  import { log } from 'effect/Console'
6
- import type { LazyArg } from 'effect/Function'
18
+ import { dual, type LazyArg } from 'effect/Function'
19
+ import type { Predicate, Refinement } from 'effect/Predicate'
7
20
 
8
21
  import { isPromise } from '../mod.ts'
9
22
  import { UnknownError } from './Error.ts'
@@ -94,6 +107,20 @@ export const tapCauseLogPretty = <R, E, A>(eff: Effect.Effect<A, E, R>): Effect.
94
107
  }),
95
108
  )
96
109
 
110
+ export const ignoreIf: {
111
+ <E, EB extends E>(
112
+ refinement: Refinement<NoInfer<E>, EB>,
113
+ ): <A, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<void, Exclude<E, EB>, R>
114
+ <E>(predicate: Predicate<NoInfer<E>>): <A, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<void, E, R>
115
+ <A, E, R, EB extends E>(
116
+ self: Effect.Effect<A, E, R>,
117
+ refinement: Refinement<E, EB>,
118
+ ): Effect.Effect<void, Exclude<E, EB>, R>
119
+ <A, E, R>(self: Effect.Effect<A, E, R>, predicate: Predicate<E>): Effect.Effect<void, E, R>
120
+ } = dual(2, <A, E, R>(self: Effect.Effect<A, E, R>, predicate: Predicate<E>) =>
121
+ self.pipe(Effect.catchIf(predicate, () => Effect.void)),
122
+ )
123
+
97
124
  export const eventListener = <TEvent = unknown>(
98
125
  target: Stream.EventListener<TEvent>,
99
126
  type: string,
@@ -166,7 +193,7 @@ export const logDuration =
166
193
  const start = Date.now()
167
194
  const res = yield* eff
168
195
  const end = Date.now()
169
- yield* Effect.log(`${label}: ${end - start}ms`)
196
+ yield* Effect.log(`${label}: ${Duration.format(end - start)}`)
170
197
  return res
171
198
  })
172
199
 
@@ -1,6 +1,6 @@
1
1
  import { Schema } from 'effect'
2
2
 
3
- export class UnknownError extends Schema.TaggedError<'UnknownError'>()('UnknownError', {
3
+ export class UnknownError extends Schema.TaggedError<UnknownError>()('UnknownError', {
4
4
  cause: Schema.Any,
5
5
  payload: Schema.optional(Schema.Any),
6
6
  }) {}
@@ -8,20 +8,24 @@ const defaultDateFormat = (date: Date): string =>
8
8
  .toString()
9
9
  .padStart(2, '0')}.${date.getMilliseconds().toString().padStart(3, '0')}`
10
10
 
11
- export const prettyWithThread = (threadName: string) =>
11
+ export const prettyWithThread = (threadName: string, options: { mode?: 'tty' | 'browser' } = {}) =>
12
12
  Logger.replace(
13
13
  Logger.defaultLogger,
14
14
  Logger.prettyLogger({
15
15
  formatDate: (date) => `${defaultDateFormat(date)} ${threadName}`,
16
+ mode: options.mode,
16
17
  }),
17
- // consoleLogger(threadName),
18
18
  )
19
19
 
20
20
  export const consoleLogger = (threadName: string) =>
21
21
  Logger.make(({ message, annotations, date, logLevel, cause }) => {
22
+ const isCloudflareWorker = typeof navigator !== 'undefined' && navigator.userAgent === 'Cloudflare-Workers'
22
23
  const consoleFn =
23
24
  logLevel === LogLevel.Debug
24
- ? console.debug
25
+ ? // Cloudflare Workers doesn't support console.debug 🤷
26
+ isCloudflareWorker
27
+ ? console.log
28
+ : console.debug
25
29
  : logLevel === LogLevel.Info
26
30
  ? console.info
27
31
  : logLevel === LogLevel.Warning
@@ -35,5 +39,11 @@ export const consoleLogger = (threadName: string) =>
35
39
  messages.push(Cause.pretty(cause, { renderErrorCause: true }))
36
40
  }
37
41
 
38
- consoleFn(`[${defaultDateFormat(date)} ${threadName}]`, ...messages, annotationsObj)
42
+ if (Object.keys(annotationsObj).length > 0) {
43
+ messages.push(annotationsObj)
44
+ }
45
+
46
+ consoleFn(`[${defaultDateFormat(date)} ${threadName}]`, ...messages)
39
47
  })
48
+
49
+ export const consoleWithThread = (threadName: string) => Logger.replace(Logger.defaultLogger, consoleLogger(threadName))
@@ -0,0 +1,11 @@
1
+ import { makeExternalSpan } from '@effect/opentelemetry/Tracer'
2
+ import type { Link as OtelSpanLink } from '@opentelemetry/api'
3
+ import type { SpanLink as EffectSpanLink } from 'effect/Tracer'
4
+
5
+ export * from '@effect/opentelemetry/Tracer'
6
+
7
+ export const makeSpanLink = (otelSpanLink: OtelSpanLink): EffectSpanLink => ({
8
+ _tag: 'SpanLink',
9
+ span: makeExternalSpan(otelSpanLink.context),
10
+ attributes: otelSpanLink.attributes ?? {},
11
+ })
@@ -0,0 +1,212 @@
1
+ export * from '@effect/rpc/RpcClient'
2
+
3
+ import { Socket } from '@effect/platform'
4
+ import { RpcClient, RpcClientError, RpcSerialization } from '@effect/rpc'
5
+ import { Protocol } from '@effect/rpc/RpcClient'
6
+ import { constPing, type FromServerEncoded } from '@effect/rpc/RpcMessage'
7
+ import { Cause, Deferred, Effect, Layer, Option, Schedule, type Scope } from 'effect'
8
+ import { constVoid, identity } from 'effect/Function'
9
+ import * as SubscriptionRef from './SubscriptionRef.ts'
10
+
11
+ // This is based on `makeProtocolSocket` / `layerProtocolSocket` from `@effect/rpc` in order to:
12
+ // - Add a `isConnected` subscription ref to track the connection state
13
+ // - Add a ping schedule to the socket
14
+ // - Add a retry schedule to the socket
15
+
16
+ export const layerProtocolSocketWithIsConnected = (options: {
17
+ readonly url: string
18
+ readonly retryTransientErrors?: Schedule.Schedule<unknown> | undefined
19
+ readonly isConnected: SubscriptionRef.SubscriptionRef<boolean>
20
+ readonly pingSchedule?: Schedule.Schedule<unknown> | undefined
21
+ }): Layer.Layer<Protocol, never, RpcSerialization.RpcSerialization | Socket.Socket> =>
22
+ Layer.scoped(Protocol, makeProtocolSocketWithIsConnected(options))
23
+
24
+ export const makeProtocolSocketWithIsConnected = (options: {
25
+ readonly url: string
26
+ readonly retryTransientErrors?: Schedule.Schedule<unknown> | undefined
27
+ // CHANGED: add isConnected subscription ref
28
+ readonly isConnected: SubscriptionRef.SubscriptionRef<boolean>
29
+ // CHANGED: add ping schedule
30
+ readonly pingSchedule?: Schedule.Schedule<unknown> | undefined
31
+ }): Effect.Effect<Protocol['Type'], never, Scope.Scope | RpcSerialization.RpcSerialization | Socket.Socket> =>
32
+ Protocol.make(
33
+ Effect.fnUntraced(function* (writeResponse) {
34
+ const socket = yield* Socket.Socket
35
+ const serialization = yield* RpcSerialization.RpcSerialization
36
+
37
+ const write = yield* socket.writer
38
+ const parser = serialization.unsafeMake()
39
+
40
+ const pinger = yield* makePinger(write(parser.encode(constPing)!), options?.pingSchedule)
41
+
42
+ yield* Effect.suspend(() => {
43
+ // We rely on the heartbeat watchdog while streaming arbitrarily long payloads.
44
+ // Reset the timer as soon as _any_ frame arrives so that large batches which
45
+ // don't contain explicit `Pong` messages don't trigger the open-timeout defect.
46
+ // (The actual pong handler still calls `onPong()` to resolve manual pings.)
47
+ // CHANGED: don't reset parser on every message
48
+ // parser = serialization.unsafeMake()
49
+ pinger.reset()
50
+ return socket
51
+ .runRaw((message) => {
52
+ try {
53
+ const responses = parser.decode(message) as Array<FromServerEncoded>
54
+ if (responses.length === 0) return
55
+ let i = 0
56
+ return Effect.whileLoop({
57
+ while: () => i < responses.length,
58
+ body: () => {
59
+ const response = responses[i++]!
60
+ // Keep extending the watchdog for each data frame to avoid
61
+ // disconnecting mid-stream when the server is busy sending batches.
62
+ pinger.reset()
63
+ if (response._tag === 'Pong') {
64
+ pinger.onPong()
65
+ }
66
+ return writeResponse(response).pipe(
67
+ // CHANGED: set isConnected to true on pong
68
+ Effect.tap(
69
+ Effect.fn(function* () {
70
+ if (options?.isConnected !== undefined) {
71
+ yield* SubscriptionRef.set(options.isConnected, true)
72
+ }
73
+ }),
74
+ ),
75
+ )
76
+ },
77
+ step: constVoid,
78
+ })
79
+ } catch (defect) {
80
+ return writeResponse({
81
+ _tag: 'ClientProtocolError',
82
+ error: new RpcClientError.RpcClientError({
83
+ reason: 'Protocol',
84
+ message: 'Error decoding message',
85
+ cause: Cause.fail(defect),
86
+ }),
87
+ })
88
+ }
89
+ })
90
+ .pipe(
91
+ Effect.raceFirst(
92
+ Effect.zipRight(
93
+ pinger.timeout,
94
+ Effect.fail(
95
+ new Socket.SocketGenericError({
96
+ reason: 'OpenTimeout',
97
+ cause: new Error('ping timeout'),
98
+ }),
99
+ ),
100
+ ),
101
+ ),
102
+ )
103
+ }).pipe(
104
+ Effect.zipRight(
105
+ Effect.fail(
106
+ new Socket.SocketCloseError({
107
+ reason: 'Close',
108
+ code: 1000,
109
+ closeReason: 'Closing connection',
110
+ }),
111
+ ),
112
+ ),
113
+ Effect.tapErrorCause(
114
+ Effect.fn(function* (cause) {
115
+ // CHANGED: set isConnected to false on error
116
+ if (options?.isConnected !== undefined) {
117
+ yield* SubscriptionRef.set(options.isConnected, false)
118
+ }
119
+
120
+ const error = Cause.failureOption(cause)
121
+ if (
122
+ options?.retryTransientErrors &&
123
+ Option.isSome(error) &&
124
+ (error.value.reason === 'Open' || error.value.reason === 'OpenTimeout')
125
+ ) {
126
+ return
127
+ }
128
+ // yield* Effect.logError('Error in socket', cause)
129
+ return yield* writeResponse({
130
+ _tag: 'ClientProtocolError',
131
+ error: new RpcClientError.RpcClientError({
132
+ reason: 'Protocol',
133
+ message: 'Error in socket',
134
+ cause: Cause.squash(cause),
135
+ }),
136
+ })
137
+ }),
138
+ ),
139
+ // CHANGED: make configurable via schedule
140
+ options?.retryTransientErrors ? Effect.retry(options.retryTransientErrors) : identity,
141
+ Effect.annotateLogs({
142
+ module: 'RpcClient',
143
+ method: 'makeProtocolSocket',
144
+ }),
145
+ Effect.interruptible,
146
+ Effect.ignore, // Errors are already handled
147
+ Effect.provide(Layer.setUnhandledErrorLogLevel(Option.none())),
148
+ Effect.forkScoped,
149
+ )
150
+
151
+ return {
152
+ send: (request) => {
153
+ const encoded = parser.encode(request)
154
+ if (encoded === undefined) return Effect.void
155
+
156
+ return Effect.orDie(write(encoded))
157
+ },
158
+ supportsAck: true,
159
+ supportsTransferables: false,
160
+ pinger,
161
+ }
162
+ }),
163
+ )
164
+
165
+ export const SocketPinger = Effect.map(RpcClient.Protocol, (protocol) => (protocol as any).pinger as SocketPinger)
166
+
167
+ export type SocketPinger = Effect.Effect.Success<ReturnType<typeof makePinger>>
168
+
169
+ const makePinger = Effect.fnUntraced(function* <A, E, R>(
170
+ writePing: Effect.Effect<A, E, R>,
171
+ pingSchedule: Schedule.Schedule<unknown> = Schedule.spaced(10000).pipe(Schedule.addDelay(() => 5000)),
172
+ ) {
173
+ // CHANGED: add manual ping deferreds
174
+ const manualPingDeferreds = new Set<Deferred.Deferred<void, never>>()
175
+
176
+ let recievedPong = true
177
+ const latch = Effect.unsafeMakeLatch()
178
+ const reset = () => {
179
+ recievedPong = true
180
+ latch.unsafeClose()
181
+ }
182
+ const onPong = () => {
183
+ recievedPong = true
184
+ // CHANGED: mark all manual ping deferreds as done
185
+ for (const deferred of manualPingDeferreds) {
186
+ Deferred.unsafeDone(deferred, Effect.void)
187
+ }
188
+ }
189
+ yield* Effect.suspend(() => {
190
+ // Starting new ping
191
+ if (!recievedPong) return latch.open
192
+ recievedPong = false
193
+ return writePing
194
+ }).pipe(
195
+ // CHANGED: make configurable via schedule
196
+ Effect.schedule(pingSchedule),
197
+ Effect.ignore,
198
+ Effect.forever,
199
+ Effect.interruptible,
200
+ Effect.forkScoped,
201
+ )
202
+
203
+ // CHANGED: add manual ping
204
+ const ping = Effect.gen(function* () {
205
+ const deferred = yield* Deferred.make<void, never>()
206
+ manualPingDeferreds.add(deferred)
207
+ yield* deferred
208
+ manualPingDeferreds.delete(deferred)
209
+ })
210
+
211
+ return { timeout: latch.await, reset, onPong, ping } as const
212
+ })
@@ -1,14 +1,13 @@
1
1
  import { Transferable } from '@effect/platform'
2
- import type { SchemaAST } from 'effect'
3
2
  import { Effect, Hash, ParseResult, Schema } from 'effect'
4
3
  import type { ParseError } from 'effect/ParseResult'
5
4
  import type { ParseOptions } from 'effect/SchemaAST'
5
+ import * as SchemaAST from 'effect/SchemaAST'
6
6
 
7
7
  import { shouldNeverHappen } from '../../mod.ts'
8
8
 
9
9
  export * from 'effect/Schema'
10
10
  export * from './debug-diff.ts'
11
- export * from './msgpack.ts'
12
11
 
13
12
  // NOTE this is a temporary workaround until Effect schema has a better way to hash schemas
14
13
  // https://github.com/Effect-TS/effect/issues/2719
@@ -24,6 +23,21 @@ export const hash = (schema: Schema.Schema<any>) => {
24
23
  }
25
24
  }
26
25
 
26
+ const resolveStructAst = (ast: SchemaAST.AST): SchemaAST.AST => {
27
+ if (SchemaAST.isTransformation(ast)) {
28
+ return resolveStructAst(ast.from)
29
+ }
30
+
31
+ return ast
32
+ }
33
+
34
+ export const getResolvedPropertySignatures = (
35
+ schema: Schema.Schema.AnyNoContext,
36
+ ): ReadonlyArray<SchemaAST.PropertySignature> => {
37
+ const resolvedAst = resolveStructAst(schema.ast)
38
+ return SchemaAST.getPropertySignatures(resolvedAst)
39
+ }
40
+
27
41
  export const encodeWithTransferables =
28
42
  <A, I, R>(schema: Schema.Schema<A, I, R>, options?: ParseOptions | undefined) =>
29
43
  (a: A, overrideOptions?: ParseOptions | undefined): Effect.Effect<[I, Transferable[]], ParseError, R> =>
@@ -82,4 +96,4 @@ export const JsonValue: Schema.Schema<JsonValue> = Schema.Union(
82
96
  Schema.Null,
83
97
  Schema.Array(Schema.suspend(() => JsonValue)),
84
98
  Schema.Record({ key: Schema.String, value: Schema.suspend(() => JsonValue) }),
85
- ).annotations({ title: 'JsonValue' })
99
+ ).annotations({ identifier: 'JsonValue' })