@livestore/utils 0.5.0-dev.0 → 0.5.0
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.
- package/dist/.tsbuildinfo +1 -1
- package/dist/Deferred.d.ts.map +1 -1
- package/dist/NoopTracer.d.ts.map +1 -1
- package/dist/NoopTracer.test.js +13 -1
- package/dist/NoopTracer.test.js.map +1 -1
- package/dist/base64.d.ts.map +1 -1
- package/dist/binary.d.ts.map +1 -1
- package/dist/browser/Opfs/Opfs.js +5 -5
- package/dist/browser/Opfs/Opfs.js.map +1 -1
- package/dist/browser/Opfs/debug-utils.d.ts.map +1 -1
- package/dist/browser/Opfs/debug-utils.js +2 -2
- package/dist/browser/Opfs/mod.js +3 -3
- package/dist/browser/Opfs/utils.d.ts +6 -6
- package/dist/browser/Opfs/utils.js +1 -1
- package/dist/browser/WebChannelBrowser.d.ts.map +1 -1
- package/dist/browser/WebChannelBrowser.js +4 -4
- package/dist/browser/WebError.d.ts +2 -2
- package/dist/browser/WebError.d.ts.map +1 -1
- package/dist/browser/WebError.js +1 -1
- package/dist/browser/WebError.js.map +1 -1
- package/dist/browser/WebError.test.js +1 -1
- package/dist/browser/WebLock.d.ts +1 -1
- package/dist/browser/WebLock.d.ts.map +1 -1
- package/dist/browser/mod.js +6 -6
- package/dist/cuid/cuid.browser.d.ts.map +1 -1
- package/dist/cuid/cuid.node.d.ts.map +1 -1
- package/dist/effect/Debug.d.ts.map +1 -1
- package/dist/effect/Debug.js +2 -4
- package/dist/effect/Debug.js.map +1 -1
- package/dist/effect/Effect.d.ts.map +1 -1
- package/dist/effect/Effect.js +5 -5
- package/dist/effect/Effect.js.map +1 -1
- package/dist/effect/Effect.test.js +2 -2
- package/dist/effect/Effect.test.js.map +1 -1
- package/dist/effect/OtelTracer.d.ts.map +1 -1
- package/dist/effect/RpcClient.d.ts +7 -7
- package/dist/effect/RpcClient.d.ts.map +1 -1
- package/dist/effect/RpcClient.js +65 -56
- package/dist/effect/RpcClient.js.map +1 -1
- package/dist/effect/Schema/debug-diff.d.ts.map +1 -1
- package/dist/effect/Schema/debug-diff.test.js +1 -1
- package/dist/effect/Schema/index.d.ts.map +1 -1
- package/dist/effect/Schema/index.js +4 -4
- package/dist/effect/Schema/index.js.map +1 -1
- package/dist/effect/Stream.d.ts.map +1 -1
- package/dist/effect/Stream.js.map +1 -1
- package/dist/effect/Stream.test.js +1 -1
- package/dist/effect/Subscribable.d.ts.map +1 -1
- package/dist/effect/SubscriptionRef.d.ts.map +1 -1
- package/dist/effect/TaskTracing.d.ts.map +1 -1
- package/dist/effect/WebChannel/WebChannel.d.ts.map +1 -1
- package/dist/effect/WebChannel/WebChannel.js +6 -6
- package/dist/effect/WebChannel/WebChannel.js.map +1 -1
- package/dist/effect/WebChannel/WebChannel.test.js +1 -1
- package/dist/effect/WebChannel/broadcastChannelWithAck.d.ts.map +1 -1
- package/dist/effect/WebChannel/broadcastChannelWithAck.js +3 -3
- package/dist/effect/WebChannel/broadcastChannelWithAck.js.map +1 -1
- package/dist/effect/WebChannel/common.d.ts.map +1 -1
- package/dist/effect/WebChannel/mod.js +3 -3
- package/dist/effect/WebSocket.d.ts +1 -1
- package/dist/effect/WebSocket.d.ts.map +1 -1
- package/dist/effect/WebSocket.js +1 -1
- package/dist/effect/WebSocket.js.map +1 -1
- package/dist/effect/WebSocket.test.js +2 -2
- package/dist/effect/WebSocket.test.js.map +1 -1
- package/dist/effect/mod.browser-build.test.js.map +1 -1
- package/dist/effect/mod.d.ts +11 -11
- package/dist/effect/mod.d.ts.map +1 -1
- package/dist/effect/mod.js +26 -26
- package/dist/effect/mod.js.map +1 -1
- package/dist/effect/spanEvent.d.ts.map +1 -1
- package/dist/effect/spanEvent.test.js +1 -1
- package/dist/env.d.ts.map +1 -1
- package/dist/env.js +1 -1
- package/dist/env.js.map +1 -1
- package/dist/fast-deep-equal.d.ts.map +1 -1
- package/dist/fast-deep-equal.js.map +1 -1
- package/dist/misc.d.ts.map +1 -1
- package/dist/misc.js +1 -1
- package/dist/misc.js.map +1 -1
- package/dist/mod.d.ts +1 -1
- package/dist/mod.d.ts.map +1 -1
- package/dist/mod.js +19 -19
- package/dist/mod.js.map +1 -1
- package/dist/node/mod.d.ts +9 -40
- package/dist/node/mod.d.ts.map +1 -1
- package/dist/node/mod.js +9 -41
- package/dist/node/mod.js.map +1 -1
- package/dist/object/index.js +1 -1
- package/dist/object/stringify-object.d.ts.map +1 -1
- package/dist/object/stringify-object.test.js +1 -1
- package/dist/promise.d.ts.map +1 -1
- package/dist/qr.d.ts.map +1 -1
- package/dist/set.d.ts.map +1 -1
- package/dist/string.d.ts.map +1 -1
- package/package.json +36 -36
- package/src/NoopTracer.test.ts +16 -0
- package/src/browser/Opfs/Opfs.ts +4 -4
- package/src/effect/Debug.ts +6 -22
- package/src/effect/Effect.test.ts +1 -1
- package/src/effect/Effect.ts +3 -3
- package/src/effect/RpcClient.ts +77 -63
- package/src/effect/Schema/index.ts +2 -2
- package/src/effect/WebChannel/WebChannel.ts +1 -2
- package/src/effect/WebSocket.test.ts +1 -1
- package/src/effect/WebSocket.ts +1 -1
- package/src/effect/mod.ts +12 -10
- package/src/fast-deep-equal.ts +4 -4
- package/src/misc.ts +1 -1
- package/src/mod.ts +5 -5
- package/src/node/mod.ts +8 -40
package/dist/node/mod.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as http from 'node:http';
|
|
2
2
|
import { NodeFileSystem } from '@effect/platform-node';
|
|
3
3
|
import { Effect, FileSystem, Layer, Option } from 'effect';
|
|
4
|
-
import { OtelTracer, Tracer, UnknownError } from
|
|
5
|
-
import { makeNoopTracer } from
|
|
6
|
-
export * as Cli from 'effect/
|
|
7
|
-
export * as SocketServer from 'effect/
|
|
4
|
+
import { OtelTracer, Tracer, UnknownError } from '../effect/mod.js';
|
|
5
|
+
import { makeNoopTracer } from '../NoopTracer.js';
|
|
6
|
+
export * as Cli from 'effect/cli';
|
|
7
|
+
export * as SocketServer from 'effect/socket/SocketServer';
|
|
8
8
|
export * as PlatformNode from '@effect/platform-node';
|
|
9
9
|
// Enable debug logging for OpenTelemetry
|
|
10
10
|
// otel.diag.setLogger(new otel.DiagConsoleLogger(), otel.DiagLogLevel.ERROR)
|
|
@@ -35,47 +35,15 @@ export const OtelLiveDummy = Layer.suspend(() => {
|
|
|
35
35
|
const TracingLive = OtelTracer.layerWithoutOtelTracer.pipe(Layer.provideMerge(OtelTracerLive));
|
|
36
36
|
return TracingLive;
|
|
37
37
|
});
|
|
38
|
+
export { NodeFileSystem };
|
|
38
39
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* NodeFileSystem layer now performs recursive watching through Node's native
|
|
43
|
-
* `fs.watch(path, { recursive: true })` fallback. This layer deliberately
|
|
44
|
-
* registers no custom backend so existing `NodeRecursiveWatchLayer` consumers
|
|
45
|
-
* continue to compile while the v4 NodeFileSystem implementation handles watch
|
|
46
|
-
* events.
|
|
47
|
-
*
|
|
48
|
-
* This layer alone does NOT provide FileSystem - it only provides the watch backend.
|
|
49
|
-
*
|
|
50
|
-
* IMPORTANT: Layer ordering matters! When composing with NodeFileSystem.layer, use
|
|
51
|
-
* `NodeFileSystemWithWatch` instead, or ensure WatchBackend is available when FileSystem
|
|
52
|
-
* is constructed by using `Layer.provideMerge`:
|
|
53
|
-
*
|
|
54
|
-
* ```ts
|
|
55
|
-
* // ✅ CORRECT: Use the pre-composed layer
|
|
56
|
-
* Effect.provide(NodeFileSystemWithWatch)
|
|
57
|
-
*
|
|
58
|
-
* // ✅ CORRECT: Manual composition with Layer.provideMerge
|
|
59
|
-
* const layer = PlatformNode.NodeFileSystem.layer.pipe(Layer.provideMerge(NodeRecursiveWatchLayer))
|
|
60
|
-
* Effect.provide(layer)
|
|
61
|
-
*
|
|
62
|
-
* // ❌ WRONG: Chained Effect.provide - WatchBackend won't be used!
|
|
63
|
-
* Effect.provide(NodeRecursiveWatchLayer).pipe(Effect.provide(PlatformNode.NodeFileSystem.layer))
|
|
64
|
-
* ```
|
|
65
|
-
*
|
|
66
|
-
* @see https://github.com/Effect-TS/effect/issues/5913
|
|
40
|
+
* Effect 4 uses Node's native recursive watcher when no custom watch backend
|
|
41
|
+
* registers for the requested path. Keep the public Effect 3 compatibility
|
|
42
|
+
* layer while deliberately deferring to that native implementation.
|
|
67
43
|
*/
|
|
68
44
|
export const NodeRecursiveWatchLayer = Layer.succeed(FileSystem.WatchBackend, FileSystem.WatchBackend.of({
|
|
69
45
|
register: () => Option.none(),
|
|
70
46
|
}));
|
|
71
|
-
/**
|
|
72
|
-
* Pre-composed layer providing FileSystem with recursive file watching.
|
|
73
|
-
* This is the recommended way to get a FileSystem that supports recursive watching.
|
|
74
|
-
*
|
|
75
|
-
* Use this layer when you need to watch files recursively (e.g., watching nested directories).
|
|
76
|
-
* Effect v4's NodeFileSystem uses Node.js's native recursive `fs.watch` support
|
|
77
|
-
* instead of the removed ParcelWatcher backend from Effect v3.
|
|
78
|
-
*/
|
|
79
|
-
export { NodeFileSystem } from '@effect/platform-node';
|
|
47
|
+
/** FileSystem layer retaining the public recursive-watch composition API. */
|
|
80
48
|
export const NodeFileSystemWithWatch = NodeFileSystem.layer.pipe(Layer.provideMerge(NodeRecursiveWatchLayer));
|
|
81
49
|
//# sourceMappingURL=mod.js.map
|
package/dist/node/mod.js.map
CHANGED
|
@@ -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,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE1D,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAEjD,OAAO,KAAK,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"mod.js","sourceRoot":"","sources":["../../src/node/mod.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AAEjC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE1D,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAEjD,OAAO,KAAK,GAAG,MAAM,YAAY,CAAA;AACjC,OAAO,KAAK,YAAY,MAAM,4BAA4B,CAAA;AAC1D,OAAO,KAAK,YAAY,MAAM,uBAAuB,CAAA;AAErD,yCAAyC;AACzC,6EAA6E;AAE7E,6EAA6E;AAE7E,MAAM,CAAC,MAAM,WAAW,GAAwC,MAAM,CAAC,QAAQ,CAAuB,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE;IACnH,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,KAAK,IAAI,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YACpD,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,UAAU,CAAC,sBAAsB,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,CAAA;IAE9F,OAAO,WAAW,CAAA;AACpB,CAAC,CAAC,CAAA;AAEF,OAAO,EAAE,cAAc,EAAE,CAAA;AAEzB;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAyC,KAAK,CAAC,OAAO,CACxF,UAAU,CAAC,YAAY,EACvB,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;IACzB,QAAQ,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE;CAC9B,CAAC,CACH,CAAA;AAED,6EAA6E;AAC7E,MAAM,CAAC,MAAM,uBAAuB,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,uBAAuB,CAAC,CAAC,CAAA"}
|
package/dist/object/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from
|
|
1
|
+
export * from './stringify-object.js';
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stringify-object.d.ts","sourceRoot":"","sources":["../../src/object/stringify-object.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,
|
|
1
|
+
{"version":3,"file":"stringify-object.d.ts","sourceRoot":"","sources":["../../src/object/stringify-object.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,QAAS,MAAM,sBAAgB,MAmB1D,CAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { stringifyObject } from
|
|
2
|
+
import { stringifyObject } from './stringify-object.js';
|
|
3
3
|
describe('stringifyObject', () => {
|
|
4
4
|
it('stringifies a flat object', () => {
|
|
5
5
|
const obj = { a: 1, b: 'test', c: true };
|
package/dist/promise.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"promise.d.ts","sourceRoot":"","sources":["../src/promise.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,eAAO,MAAM,UAAU,GAAI,CAAC,EAAE,GAAG,
|
|
1
|
+
{"version":3,"file":"promise.d.ts","sourceRoot":"","sources":["../src/promise.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,eAAO,MAAM,UAAU,GAAI,CAAC,EAAE,GAAG,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,6CACpE,CAAA;AAE3B,eAAO,MAAM,cAAc,GAAU,CAAC,EAAE,GAAG,QACnC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,OAClB,CAAC,EAAE,EAAE,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,KACjD,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAG7B,CAAA;AAED,eAAO,MAAM,gBAAgB,GAAU,CAAC,EAAE,GAAG,OACtC,CAAC,EAAE,YACE,CAAC,EAAE,EAAE,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,UAC/C,CAAC,EAAE,EAAE,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,MAAM,KACxC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAI7B,CAAA;AAED,eAAO,MAAM,cAAc,GAAU,CAAC,EAAE,GAAG,OACpC,CAAC,EAAE,OACH,CAAC,EAAE,EAAE,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,CAAC,aACjC,MAAM,KAChB,OAAO,CAAC,GAAG,EAAE,CAgBf,CAAA"}
|
package/dist/qr.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qr.d.ts","sourceRoot":"","sources":["../src/qr.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,IAAI,EAAE,EAAE,MAAM,kBAAkB,CAAA;AAEhD,MAAM,MAAM,sBAAsB,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAA;AAE1D,MAAM,MAAM,sBAAsB,GAAG;IACnC,oBAAoB,CAAC,EAAE,sBAAsB,CAAA;IAC7C,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,gDAAgD;IAChD,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,oFAAoF;IACpF,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,eAAe,
|
|
1
|
+
{"version":3,"file":"qr.d.ts","sourceRoot":"","sources":["../src/qr.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,IAAI,EAAE,EAAE,MAAM,kBAAkB,CAAA;AAEhD,MAAM,MAAM,sBAAsB,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAA;AAE1D,MAAM,MAAM,sBAAsB,GAAG;IACnC,oBAAoB,CAAC,EAAE,sBAAsB,CAAA;IAC7C,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,gDAAgD;IAChD,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,oFAAoF;IACpF,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,eAAe,SAAU,MAAM,YAAY,sBAAsB,KAAG,IAmFhF,CAAA"}
|
package/dist/set.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"set.d.ts","sourceRoot":"","sources":["../src/set.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,GAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"set.d.ts","sourceRoot":"","sources":["../src/set.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,GAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,WASjD,CAAA"}
|
package/dist/string.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"string.d.ts","sourceRoot":"","sources":["../src/string.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,eAAO,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"string.d.ts","sourceRoot":"","sources":["../src/string.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,eAAO,MAAM,MAAM,QAAS,MAAM,KAAK,MAAM,oBAAe,MAI7C,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
"$genie": {
|
|
3
|
+
"source": "package.json.genie.ts",
|
|
4
|
+
"warning": "DO NOT EDIT - changes will be overwritten",
|
|
5
|
+
"workspaceClosureDirs": [
|
|
6
|
+
"packages/@livestore/utils"
|
|
7
|
+
]
|
|
8
8
|
},
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
"package.json",
|
|
12
|
-
"src"
|
|
13
|
-
],
|
|
9
|
+
"name": "@livestore/utils",
|
|
10
|
+
"version": "0.5.0",
|
|
14
11
|
"type": "module",
|
|
15
12
|
"sideEffects": [
|
|
16
13
|
"./src/global.ts",
|
|
17
14
|
"./dist/global.js"
|
|
18
15
|
],
|
|
19
|
-
"
|
|
16
|
+
"license": "Apache-2.0",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/livestorejs/livestore.git"
|
|
20
|
+
},
|
|
20
21
|
"exports": {
|
|
21
22
|
".": {
|
|
22
23
|
"types": "./dist/mod.d.ts",
|
|
@@ -53,23 +54,25 @@
|
|
|
53
54
|
"default": "./dist/bun/mod.js"
|
|
54
55
|
}
|
|
55
56
|
},
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
|
|
57
|
+
"files": [
|
|
58
|
+
"dist",
|
|
59
|
+
"package.json",
|
|
60
|
+
"src"
|
|
61
|
+
],
|
|
59
62
|
"dependencies": {
|
|
60
|
-
"@effect/platform-node": "4.0.
|
|
63
|
+
"@effect/platform-node": "4.0.3",
|
|
61
64
|
"@standard-schema/spec": "1.1.0",
|
|
62
65
|
"nanoid": "5.0.9",
|
|
63
66
|
"pretty-bytes": "7.0.1",
|
|
64
67
|
"qrcode-generator": "2.0.4"
|
|
65
68
|
},
|
|
66
69
|
"devDependencies": {
|
|
67
|
-
"@effect/opentelemetry": "4.0.
|
|
68
|
-
"@effect/platform-browser": "4.0.
|
|
69
|
-
"@effect/platform-bun": "4.0.
|
|
70
|
-
"@effect/platform-node": "4.0.
|
|
71
|
-
"@effect/platform-node-shared": "4.0.
|
|
72
|
-
"@effect/vitest": "4.0.
|
|
70
|
+
"@effect/opentelemetry": "4.0.3",
|
|
71
|
+
"@effect/platform-browser": "4.0.3",
|
|
72
|
+
"@effect/platform-bun": "4.0.3",
|
|
73
|
+
"@effect/platform-node": "4.0.3",
|
|
74
|
+
"@effect/platform-node-shared": "4.0.3",
|
|
75
|
+
"@effect/vitest": "4.0.3",
|
|
73
76
|
"@opentelemetry/api": "1.9.0",
|
|
74
77
|
"@opentelemetry/resources": "2.2.0",
|
|
75
78
|
"@standard-schema/spec": "1.1.0",
|
|
@@ -77,30 +80,27 @@
|
|
|
77
80
|
"@types/jsdom": "21.1.7",
|
|
78
81
|
"@types/node": "25.3.3",
|
|
79
82
|
"@types/web": "0.0.264",
|
|
80
|
-
"effect": "4.0.
|
|
83
|
+
"effect": "4.0.3",
|
|
81
84
|
"esbuild": "0.28.0",
|
|
82
85
|
"jsdom": "26.1.0",
|
|
83
86
|
"vitest": "4.1.9"
|
|
84
87
|
},
|
|
85
88
|
"peerDependencies": {
|
|
86
|
-
"@effect/opentelemetry": "^4.0.
|
|
87
|
-
"@effect/platform-browser": "^4.0.
|
|
88
|
-
"@effect/platform-bun": "^4.0.
|
|
89
|
-
"@effect/platform-node": "^4.0.
|
|
90
|
-
"@effect/platform-node-shared": "^4.0.
|
|
91
|
-
"@effect/vitest": "^4.0.
|
|
89
|
+
"@effect/opentelemetry": "^4.0.3",
|
|
90
|
+
"@effect/platform-browser": "^4.0.3",
|
|
91
|
+
"@effect/platform-bun": "^4.0.3",
|
|
92
|
+
"@effect/platform-node": "^4.0.3",
|
|
93
|
+
"@effect/platform-node-shared": "^4.0.3",
|
|
94
|
+
"@effect/vitest": "^4.0.3",
|
|
92
95
|
"@opentelemetry/api": "^1.9.0",
|
|
93
96
|
"@opentelemetry/resources": "^2.2.0",
|
|
94
97
|
"@standard-schema/spec": "^1.1.0",
|
|
95
|
-
"effect": "^4.0.
|
|
98
|
+
"effect": "^4.0.3"
|
|
96
99
|
},
|
|
97
|
-
"
|
|
98
|
-
"
|
|
99
|
-
"warning": "DO NOT EDIT - changes will be overwritten",
|
|
100
|
-
"workspaceClosureDirs": [
|
|
101
|
-
"packages/@livestore/utils"
|
|
102
|
-
]
|
|
100
|
+
"publishConfig": {
|
|
101
|
+
"access": "public"
|
|
103
102
|
},
|
|
103
|
+
"react-native": "./dist/index.js",
|
|
104
104
|
"scripts": {
|
|
105
105
|
"test": "vitest"
|
|
106
106
|
}
|
package/src/NoopTracer.test.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { INVALID_SPAN_CONTEXT, isSpanContextValid, ROOT_CONTEXT } from '@opentelemetry/api'
|
|
2
|
+
import { Effect, FileSystem, type Layer } from 'effect'
|
|
2
3
|
import { describe, expect, it } from 'vitest'
|
|
3
4
|
|
|
5
|
+
import { NodeFileSystemWithWatch, NodeRecursiveWatchLayer } from '@livestore/utils/node'
|
|
6
|
+
|
|
4
7
|
import { makeNoopSpan, makeNoopTracer } from './NoopTracer.ts'
|
|
5
8
|
|
|
6
9
|
describe('NoopTracer', () => {
|
|
@@ -18,3 +21,16 @@ describe('NoopTracer', () => {
|
|
|
18
21
|
expect(tracer.startActiveSpan('four arguments', {}, ROOT_CONTEXT, () => 'four')).toBe('four')
|
|
19
22
|
})
|
|
20
23
|
})
|
|
24
|
+
|
|
25
|
+
describe('@livestore/utils/node recursive watch compatibility', () => {
|
|
26
|
+
it('keeps the public layers type-compatible and runnable', async () => {
|
|
27
|
+
const watchLayer: Layer.Layer<FileSystem.WatchBackend> = NodeRecursiveWatchLayer
|
|
28
|
+
const fileSystemLayer: Layer.Layer<FileSystem.FileSystem> = NodeFileSystemWithWatch
|
|
29
|
+
|
|
30
|
+
const watchBackend = await Effect.runPromise(FileSystem.WatchBackend.pipe(Effect.provide(watchLayer)))
|
|
31
|
+
const fileSystem = await Effect.runPromise(FileSystem.FileSystem.pipe(Effect.provide(fileSystemLayer)))
|
|
32
|
+
|
|
33
|
+
expect(typeof watchBackend.register).toBe('function')
|
|
34
|
+
expect(typeof fileSystem.watch).toBe('function')
|
|
35
|
+
})
|
|
36
|
+
})
|
package/src/browser/Opfs/Opfs.ts
CHANGED
|
@@ -308,7 +308,7 @@ export const layer = Layer.succeed(
|
|
|
308
308
|
Effect.tryPromise({
|
|
309
309
|
try: () => stream.close(),
|
|
310
310
|
catch: (u) => WebError.classifyWebError(u, [WebError.TypeError]),
|
|
311
|
-
}).pipe(Effect.
|
|
311
|
+
}).pipe(Effect.ignoreCause),
|
|
312
312
|
),
|
|
313
313
|
appendToFile: (handle: FileSystemFileHandle, data: FileSystemWriteChunkType) =>
|
|
314
314
|
Effect.acquireUseRelease(
|
|
@@ -346,7 +346,7 @@ export const layer = Layer.succeed(
|
|
|
346
346
|
Effect.tryPromise({
|
|
347
347
|
try: () => stream.close(),
|
|
348
348
|
catch: (u) => WebError.classifyWebError(u, [WebError.TypeError]),
|
|
349
|
-
}).pipe(Effect.
|
|
349
|
+
}).pipe(Effect.ignoreCause),
|
|
350
350
|
),
|
|
351
351
|
truncateFile: (handle: FileSystemFileHandle, size: number) =>
|
|
352
352
|
Effect.acquireUseRelease(
|
|
@@ -370,7 +370,7 @@ export const layer = Layer.succeed(
|
|
|
370
370
|
Effect.tryPromise({
|
|
371
371
|
try: () => stream.close(),
|
|
372
372
|
catch: (u) => WebError.classifyWebError(u, [WebError.TypeError]),
|
|
373
|
-
}).pipe(Effect.
|
|
373
|
+
}).pipe(Effect.ignoreCause),
|
|
374
374
|
),
|
|
375
375
|
createSyncAccessHandle: (handle: FileSystemFileHandle) =>
|
|
376
376
|
Effect.acquireRelease(
|
|
@@ -440,7 +440,7 @@ export const layerNoop = Layer.succeed(
|
|
|
440
440
|
getDirectoryHandle: () => Effect.fail(notFoundError),
|
|
441
441
|
removeEntry: () => Effect.fail(notFoundError),
|
|
442
442
|
values: () => Stream.fail(notFoundError),
|
|
443
|
-
resolve: () => Effect.
|
|
443
|
+
resolve: () => Effect.succeedNone,
|
|
444
444
|
getFile: () => Effect.fail(notFoundError),
|
|
445
445
|
writeFile: () => Effect.fail(notFoundError),
|
|
446
446
|
appendToFile: () => Effect.fail(notFoundError),
|
package/src/effect/Debug.ts
CHANGED
|
@@ -194,24 +194,12 @@ const ensureTracerPatched = (tracer: Tracer.Tracer) => {
|
|
|
194
194
|
}
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
-
interface ScopeImpl extends Scope.Scope {
|
|
198
|
-
readonly state:
|
|
199
|
-
| {
|
|
200
|
-
readonly _tag: 'Open'
|
|
201
|
-
readonly finalizers: Map<{}, (exit: Exit.Exit<unknown, unknown>) => Effect.Effect<unknown>>
|
|
202
|
-
}
|
|
203
|
-
| {
|
|
204
|
-
readonly _tag: 'Closed'
|
|
205
|
-
readonly exit: Exit.Exit<unknown, unknown>
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
|
|
209
197
|
const knownScopes = new Map<
|
|
210
|
-
|
|
198
|
+
Scope.Scope,
|
|
211
199
|
{ id: number; allocationFiber: Fiber.Fiber<any, any> | undefined; allocationSpan: Tracer.AnySpan | undefined }
|
|
212
200
|
>()
|
|
213
201
|
let lastScopeId = 0
|
|
214
|
-
const ensureScopePatched = (scope:
|
|
202
|
+
const ensureScopePatched = (scope: Scope.Scope, allocationFiber: Fiber.Fiber<any, any> | undefined) => {
|
|
215
203
|
if (scope.state._tag === 'Closed') return
|
|
216
204
|
if (knownScopes.has(scope) === true) return
|
|
217
205
|
const id = lastScopeId++
|
|
@@ -232,7 +220,7 @@ const ensureScopePatched = (scope: ScopeImpl, allocationFiber: Fiber.Fiber<any,
|
|
|
232
220
|
} else {
|
|
233
221
|
cleanupScopes()
|
|
234
222
|
}
|
|
235
|
-
const allocationSpan = allocationFiber?.
|
|
223
|
+
const allocationSpan = allocationFiber?.cache.span
|
|
236
224
|
knownScopes.set(scope, { id, allocationFiber, allocationSpan })
|
|
237
225
|
}
|
|
238
226
|
const cleanupScopes = () => {
|
|
@@ -247,8 +235,7 @@ const ensureFiberPatched = (fiber: Fiber.Fiber<any, any>) => {
|
|
|
247
235
|
ensureTracerPatched(fiber.getRef(Tracer.Tracer))
|
|
248
236
|
// patch scope
|
|
249
237
|
const currentScope = Context.getOrElse(fiber.context, Scope.Scope, () => undefined)
|
|
250
|
-
|
|
251
|
-
if (currentScope !== undefined) ensureScopePatched(currentScope as any as ScopeImpl, undefined)
|
|
238
|
+
if (currentScope !== undefined) ensureScopePatched(currentScope, undefined)
|
|
252
239
|
// patch fiber
|
|
253
240
|
if (knownFibers.has(fiber) === true) return
|
|
254
241
|
knownFibers.add(fiber)
|
|
@@ -296,8 +283,7 @@ export const attachSlowDebugInstrumentation = (options: {
|
|
|
296
283
|
console.log('onEvent', event)
|
|
297
284
|
switch (event._tag) {
|
|
298
285
|
case 'ScopeAllocated':
|
|
299
|
-
|
|
300
|
-
ensureScopePatched(event.scope as any as ScopeImpl, _globalThis['~effect/Fiber/currentFiber'])
|
|
286
|
+
ensureScopePatched(event.scope, _globalThis['~effect/Fiber/currentFiber'])
|
|
301
287
|
break
|
|
302
288
|
case 'FiberAllocated':
|
|
303
289
|
ensureFiberPatched(event.fiber)
|
|
@@ -377,9 +363,7 @@ const renderSpanNode = (graph: Graph.Graph<GraphNodeInfo, void, 'directed'>, nod
|
|
|
377
363
|
const durationStr = duration !== undefined ? ` ${duration}` : ''
|
|
378
364
|
|
|
379
365
|
const fiberIds = Array.from(knownFibers)
|
|
380
|
-
.filter(
|
|
381
|
-
(fiber) => fiber.currentSpan?.spanId === info.span.spanId && fiber.currentSpan?.traceId === info.span.traceId,
|
|
382
|
-
)
|
|
366
|
+
.filter((fiber) => fiber.cache.span?.spanId === info.span.spanId && fiber.cache.span?.traceId === info.span.traceId)
|
|
383
367
|
.map((fiber) => `#${fiber.id}`)
|
|
384
368
|
.join(', ')
|
|
385
369
|
const runningOnFibers = fiberIds.length > 0 ? ` [fibers ${fiberIds}]` : ''
|
|
@@ -67,7 +67,7 @@ describe('trySyncOrPromiseOrEffect', () => {
|
|
|
67
67
|
Effect.gen(function* () {
|
|
68
68
|
const thrown = new Error('throwing then getter')
|
|
69
69
|
const thenable = {
|
|
70
|
-
// oxlint-disable-next-line
|
|
70
|
+
// oxlint-disable-next-line unicorn/no-thenable -- intentionally exercises Promise-like classification
|
|
71
71
|
get then(): PromiseLike<never>['then'] {
|
|
72
72
|
throw thrown
|
|
73
73
|
},
|
package/src/effect/Effect.ts
CHANGED
|
@@ -129,7 +129,7 @@ export const tapCauseLogPretty = <R, E, A>(eff: Effect.Effect<A, E, R>): Effect.
|
|
|
129
129
|
export const dieDebugger = (msg: string, ...args: ReadonlyArray<unknown>): Effect.Effect<never> =>
|
|
130
130
|
Effect.suspend(() => {
|
|
131
131
|
if (isDevEnv() === true) {
|
|
132
|
-
// oxlint-disable-next-line
|
|
132
|
+
// oxlint-disable-next-line no-debugger -- intentional breakpoint during development
|
|
133
133
|
debugger
|
|
134
134
|
void args // Keeps the variable in scope so it's inspectable when the debugger pauses
|
|
135
135
|
}
|
|
@@ -150,7 +150,7 @@ export const orDieDebugger = <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Eff
|
|
|
150
150
|
// Keep the debugger hook so that `debugger` runs only when the wrapped effect actually fails, not while building the wrapper.
|
|
151
151
|
Effect.suspend(() => {
|
|
152
152
|
if (isDevEnv() === true) {
|
|
153
|
-
// oxlint-disable-next-line
|
|
153
|
+
// oxlint-disable-next-line no-debugger -- intentional breakpoint for impossible states during development
|
|
154
154
|
debugger
|
|
155
155
|
}
|
|
156
156
|
return Effect.die(error)
|
|
@@ -342,7 +342,7 @@ export const withPerformanceMeasure =
|
|
|
342
342
|
|
|
343
343
|
const getSpanTrace = () => {
|
|
344
344
|
const fiber = Fiber.getCurrent()
|
|
345
|
-
if (fiber === undefined || fiber.
|
|
345
|
+
if (fiber === undefined || fiber.cache.span === undefined) {
|
|
346
346
|
return 'No current fiber'
|
|
347
347
|
}
|
|
348
348
|
|
package/src/effect/RpcClient.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
export * from 'effect/
|
|
1
|
+
export * from 'effect/rpc/RpcClient'
|
|
2
2
|
|
|
3
3
|
import { Cause, Deferred, Effect, Function, Latch, Layer, References, Result, Schedule, type Scope } from 'effect'
|
|
4
|
-
import { RpcClient, RpcClientError, RpcSerialization } from 'effect/
|
|
5
|
-
import { Protocol } from 'effect/
|
|
6
|
-
import { constPing, type FromServerEncoded } from 'effect/
|
|
7
|
-
import { Socket } from 'effect/
|
|
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 { Socket } from 'effect/socket'
|
|
8
8
|
|
|
9
9
|
import * as SubscriptionRef from './SubscriptionRef.ts'
|
|
10
10
|
|
|
@@ -35,81 +35,94 @@ export const makeProtocolSocketWithIsConnected = (options: {
|
|
|
35
35
|
const serialization = yield* RpcSerialization.RpcSerialization
|
|
36
36
|
const requestClientMap = new Map<string | number, number>()
|
|
37
37
|
|
|
38
|
-
const
|
|
38
|
+
const writer = yield* socket.writer
|
|
39
39
|
let parser = serialization.makeUnsafe()
|
|
40
40
|
|
|
41
|
-
const pinger = yield* makePinger(
|
|
41
|
+
const pinger = yield* makePinger(
|
|
42
|
+
Effect.suspend(() => {
|
|
43
|
+
const encoded = parser.encode(constPing)
|
|
44
|
+
return encoded === undefined ? Effect.void : writer.write(encoded)
|
|
45
|
+
}),
|
|
46
|
+
options?.pingSchedule,
|
|
47
|
+
)
|
|
42
48
|
let currentError: RpcClientError.RpcClientError | undefined
|
|
43
49
|
|
|
44
50
|
const markConnected = SubscriptionRef.set(options.isConnected, true)
|
|
45
51
|
const broadcast = (response: FromServerEncoded) =>
|
|
46
52
|
Effect.forEach(clientIds, (clientId) => writeResponse(clientId, response))
|
|
47
53
|
|
|
54
|
+
const processData = (message: Uint8Array | string): Effect.Effect<void> => {
|
|
55
|
+
try {
|
|
56
|
+
const responses = parser.decode(message) as Array<FromServerEncoded>
|
|
57
|
+
if (responses.length === 0) return Effect.void
|
|
58
|
+
let i = 0
|
|
59
|
+
return Effect.whileLoop({
|
|
60
|
+
while: () => i < responses.length,
|
|
61
|
+
body: () => {
|
|
62
|
+
const response = responses[i++]!
|
|
63
|
+
pinger.reset()
|
|
64
|
+
if (response._tag === 'Pong') {
|
|
65
|
+
pinger.onPong()
|
|
66
|
+
return markConnected
|
|
67
|
+
}
|
|
68
|
+
if ('requestId' in response) {
|
|
69
|
+
const clientId = requestClientMap.get(response.requestId)
|
|
70
|
+
if (clientId !== undefined) {
|
|
71
|
+
if (response._tag === 'Exit') {
|
|
72
|
+
requestClientMap.delete(response.requestId)
|
|
73
|
+
}
|
|
74
|
+
return markConnected.pipe(Effect.andThen(writeResponse(clientId, response)))
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return markConnected.pipe(Effect.andThen(broadcast(response)))
|
|
78
|
+
},
|
|
79
|
+
step: Function.constVoid,
|
|
80
|
+
})
|
|
81
|
+
} catch (defect) {
|
|
82
|
+
return broadcast({
|
|
83
|
+
_tag: 'ClientProtocolError',
|
|
84
|
+
error: new RpcClientError.RpcClientError({
|
|
85
|
+
reason: new RpcClientError.RpcClientDefect({
|
|
86
|
+
message: 'Error decoding message',
|
|
87
|
+
cause: defect,
|
|
88
|
+
}),
|
|
89
|
+
}),
|
|
90
|
+
})
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
48
94
|
yield* Effect.suspend(() => {
|
|
49
95
|
// We rely on the heartbeat watchdog while streaming arbitrarily long payloads.
|
|
50
96
|
// Reset the timer as soon as _any_ frame arrives so that large batches which
|
|
51
97
|
// don't contain explicit `Pong` messages don't trigger the open-timeout defect.
|
|
52
98
|
// (The actual pong handler still calls `onPong()` to resolve manual pings.)
|
|
53
|
-
|
|
54
|
-
// parser = serialization.makeUnsafe()
|
|
55
|
-
currentError = undefined
|
|
99
|
+
parser = serialization.makeUnsafe()
|
|
56
100
|
pinger.reset()
|
|
57
|
-
return
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
body: () => {
|
|
66
|
-
const response = responses[i++]!
|
|
67
|
-
// Keep extending the watchdog for each data frame to avoid
|
|
68
|
-
// disconnecting mid-stream when the server is busy sending batches.
|
|
69
|
-
pinger.reset()
|
|
70
|
-
if (response._tag === 'Pong') {
|
|
71
|
-
pinger.onPong()
|
|
72
|
-
return markConnected
|
|
73
|
-
}
|
|
74
|
-
if ('requestId' in response) {
|
|
75
|
-
const clientId = requestClientMap.get(response.requestId)
|
|
76
|
-
if (clientId !== undefined) {
|
|
77
|
-
if (response._tag === 'Exit') {
|
|
78
|
-
requestClientMap.delete(response.requestId)
|
|
79
|
-
}
|
|
80
|
-
return markConnected.pipe(Effect.andThen(writeResponse(clientId, response)))
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return markConnected.pipe(Effect.andThen(broadcast(response)))
|
|
84
|
-
},
|
|
85
|
-
step: Function.constVoid,
|
|
86
|
-
})
|
|
87
|
-
} catch (defect) {
|
|
88
|
-
return broadcast({
|
|
89
|
-
_tag: 'ClientProtocolError',
|
|
90
|
-
error: new RpcClientError.RpcClientError({
|
|
91
|
-
reason: new RpcClientError.RpcClientDefect({
|
|
92
|
-
message: 'Error decoding message',
|
|
93
|
-
cause: defect,
|
|
94
|
-
}),
|
|
95
|
-
}),
|
|
96
|
-
})
|
|
101
|
+
return Effect.gen(function* () {
|
|
102
|
+
const { pull } = yield* socket.reader
|
|
103
|
+
currentError = undefined
|
|
104
|
+
while (true) {
|
|
105
|
+
const frames = yield* pull
|
|
106
|
+
for (const frame of frames) {
|
|
107
|
+
// Keep extending the watchdog for each data frame to avoid disconnecting mid-stream.
|
|
108
|
+
yield* processData(frame)
|
|
97
109
|
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
110
|
+
}
|
|
111
|
+
}).pipe(
|
|
112
|
+
Effect.scoped,
|
|
113
|
+
Effect.raceFirst(
|
|
114
|
+
Effect.flatMap(pinger.timeout, () =>
|
|
115
|
+
Effect.fail(
|
|
116
|
+
new Socket.SocketError({
|
|
117
|
+
reason: new Socket.SocketOpenError({
|
|
118
|
+
kind: 'Timeout',
|
|
119
|
+
cause: new Error('ping timeout'),
|
|
108
120
|
}),
|
|
109
|
-
),
|
|
121
|
+
}),
|
|
110
122
|
),
|
|
111
123
|
),
|
|
112
|
-
)
|
|
124
|
+
),
|
|
125
|
+
)
|
|
113
126
|
}).pipe(
|
|
114
127
|
Effect.flatMap(() =>
|
|
115
128
|
Effect.fail(
|
|
@@ -173,10 +186,11 @@ export const makeProtocolSocketWithIsConnected = (options: {
|
|
|
173
186
|
const encoded = parser.encode(request)
|
|
174
187
|
if (encoded === undefined) return Effect.void
|
|
175
188
|
|
|
176
|
-
return Effect.orDie(write(encoded))
|
|
189
|
+
return Effect.orDie(writer.write(encoded))
|
|
177
190
|
},
|
|
178
191
|
supportsAck: true,
|
|
179
192
|
supportsTransferables: false,
|
|
193
|
+
codecFor: serialization.codecFor,
|
|
180
194
|
pinger,
|
|
181
195
|
}
|
|
182
196
|
}),
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
SchemaTransformation,
|
|
13
13
|
Struct,
|
|
14
14
|
} from 'effect'
|
|
15
|
-
import { Transferable } from 'effect/
|
|
15
|
+
import { Transferable } from 'effect/workers'
|
|
16
16
|
|
|
17
17
|
import { shouldNeverHappen } from '../../misc.ts'
|
|
18
18
|
|
|
@@ -89,7 +89,7 @@ export const headOrElse: {
|
|
|
89
89
|
array.pipe(
|
|
90
90
|
Schema.decodeTo(
|
|
91
91
|
Schema.toType(array.value),
|
|
92
|
-
SchemaTransformation.
|
|
92
|
+
SchemaTransformation.transformEffect({
|
|
93
93
|
decode: (array) =>
|
|
94
94
|
Array.isReadonlyArrayNonEmpty(array) === true
|
|
95
95
|
? Effect.succeed(Array.headNonEmpty(array))
|
|
@@ -378,8 +378,7 @@ export const toOpenChannel = <MsgListen, MsgSend>(
|
|
|
378
378
|
const deferred = yield* Deferred.make<void>()
|
|
379
379
|
pendingPingDeferredRef.current = { deferred, requestId }
|
|
380
380
|
yield* Deferred.await(deferred).pipe(
|
|
381
|
-
Effect.timeout(
|
|
382
|
-
Effect.catchTag('TimeoutError', () => channel.shutdown),
|
|
381
|
+
Effect.timeoutOrElse({ duration: timeout, orElse: () => channel.shutdown }),
|
|
383
382
|
)
|
|
384
383
|
}
|
|
385
384
|
}).pipe(Effect.withSpan(`WebChannel:heartbeat`), Effect.forkScoped)
|
package/src/effect/WebSocket.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Schedule, Scope } from 'effect'
|
|
2
2
|
import { Effect, Exit, identity, Schema } from 'effect'
|
|
3
|
-
import { HttpClient } from 'effect/
|
|
3
|
+
import { HttpClient } from 'effect/http'
|
|
4
4
|
|
|
5
5
|
export class WebSocketError extends Schema.TaggedError<WebSocketError>('~@livestore/utils/WebSocketError')(
|
|
6
6
|
'WebSocketError',
|