foldkit-remote 0.11.0 → 0.13.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/README.md +36 -1
- package/dist/index-Dh4qdXfE.d.mts +3531 -0
- package/dist/index-Dh4qdXfE.d.mts.map +1 -0
- package/dist/index.d.mts +2 -3493
- package/dist/index.mjs +2 -5072
- package/dist/port.d.mts +28 -0
- package/dist/port.d.mts.map +1 -0
- package/dist/port.mjs +81 -0
- package/dist/port.mjs.map +1 -0
- package/dist/src-C53_fLA2.mjs +5148 -0
- package/dist/src-C53_fLA2.mjs.map +1 -0
- package/package.json +8 -3
- package/dist/index.d.mts.map +0 -1
- package/dist/index.mjs.map +0 -1
package/dist/port.d.mts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Mt as RemoteClient } from "./index-Dh4qdXfE.mjs";
|
|
2
|
+
import { Effect, Layer } from "effect";
|
|
3
|
+
import { RpcClient } from "effect/rpc";
|
|
4
|
+
import * as WorkerRunner from "effect/workers/WorkerRunner";
|
|
5
|
+
import { WorkerError } from "effect/workers/WorkerError";
|
|
6
|
+
//#region src/port.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* Effect's RPC worker protocol over a `MessagePort`: what `port` runs on, for
|
|
9
|
+
* an RPC client of `RemoteRpc` made by hand. `open` is called for each
|
|
10
|
+
* connection the protocol makes (once, and again if it restarts), so it opens
|
|
11
|
+
* a new conversation each time, such as a `MessageChannel` whose other port
|
|
12
|
+
* goes to the server.
|
|
13
|
+
*/
|
|
14
|
+
export declare const portProtocol: (open: () => MessagePort) => Layer.Layer<RpcClient.Protocol, WorkerError>;
|
|
15
|
+
/** Remote's client over a `MessagePort`: `portProtocol` under `Remote.clientLayer`. */
|
|
16
|
+
export declare const port: (open: () => MessagePort) => Layer.Layer<RemoteClient>;
|
|
17
|
+
/**
|
|
18
|
+
* The server's side of one port: Effect's `WorkerRunnerPlatform` over a single
|
|
19
|
+
* `MessagePort`, for `RpcServer.layerProtocolWorkerRunner`, and `closed`,
|
|
20
|
+
* which completes when the client closes its end. `foldkit-remote-server/port`
|
|
21
|
+
* uses it.
|
|
22
|
+
*/
|
|
23
|
+
export declare const portRunner: (served: MessagePort) => {
|
|
24
|
+
readonly platform: WorkerRunner.WorkerRunnerPlatform["Service"];
|
|
25
|
+
readonly closed: Effect.Effect<void>;
|
|
26
|
+
};
|
|
27
|
+
//#endregion
|
|
28
|
+
//# sourceMappingURL=port.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"port.d.mts","names":[],"sources":["../src/port.ts"],"mappings":";;;;;;;;;;;;;qBA8Ca,eACX,YAAY,gBACX,MAAM,MAAM,UAAU,UAAU;;qBAWtB,OAAQ,YAAY,gBAAc,MAAM,MAAM;;;;;;;qBAc9C,aACX,QAAQ;WAEC,UAAU,aAAa;WACvB,QAAQ,OAAO"}
|
package/dist/port.mjs
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { an as RemoteRpc, t as Remote } from "./src-C53_fLA2.mjs";
|
|
2
|
+
import { Deferred, Effect, Exit, Layer, Queue, Scope } from "effect";
|
|
3
|
+
import { RpcClient } from "effect/rpc";
|
|
4
|
+
import * as Worker from "effect/workers/Worker";
|
|
5
|
+
import "effect/workers/WorkerRunner";
|
|
6
|
+
//#region src/port.ts
|
|
7
|
+
/**
|
|
8
|
+
* `foldkit-remote/port`: Remote over a `MessagePort`, for a server in a
|
|
9
|
+
* worker or in the page (a sandbox). It speaks Effect's own RPC worker
|
|
10
|
+
* protocol over the port, so reads, queries, mutations and live streams, their
|
|
11
|
+
* typed errors and interruption all cross it; `foldkit-remote-server/port`
|
|
12
|
+
* serves the other end.
|
|
13
|
+
*
|
|
14
|
+
* Built on `effect/workers` alone: a `MessagePort` platform for the client and
|
|
15
|
+
* a one-port runner for the server, no browser package.
|
|
16
|
+
*/
|
|
17
|
+
const platform = Worker.makePlatform()({
|
|
18
|
+
setup: ({ worker, scope }) => Effect.as(Scope.addFinalizer(scope, Effect.sync(() => worker.postMessage([1]))), worker),
|
|
19
|
+
listen: ({ port, emit, scope }) => {
|
|
20
|
+
const onMessage = (event) => emit(event.data);
|
|
21
|
+
port.addEventListener("message", onMessage);
|
|
22
|
+
port.start();
|
|
23
|
+
return Scope.addFinalizer(scope, Effect.sync(() => port.removeEventListener("message", onMessage)));
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
/**
|
|
27
|
+
* Effect's RPC worker protocol over a `MessagePort`: what `port` runs on, for
|
|
28
|
+
* an RPC client of `RemoteRpc` made by hand. `open` is called for each
|
|
29
|
+
* connection the protocol makes (once, and again if it restarts), so it opens
|
|
30
|
+
* a new conversation each time, such as a `MessageChannel` whose other port
|
|
31
|
+
* goes to the server.
|
|
32
|
+
*/
|
|
33
|
+
const portProtocol = (open) => RpcClient.layerProtocolWorker({ size: 1 }).pipe(Layer.provide(Layer.merge(Layer.succeed(Worker.WorkerPlatform)(platform), Worker.layerSpawner(() => open()))));
|
|
34
|
+
/** Remote's client over a `MessagePort`: `portProtocol` under `Remote.clientLayer`. */
|
|
35
|
+
const port = (open) => Layer.unwrap(Effect.map(RpcClient.make(RemoteRpc), (client) => Remote.clientLayer(client))).pipe(Layer.provide(portProtocol(open)), Layer.orDie);
|
|
36
|
+
/**
|
|
37
|
+
* The server's side of one port: Effect's `WorkerRunnerPlatform` over a single
|
|
38
|
+
* `MessagePort`, for `RpcServer.layerProtocolWorkerRunner`, and `closed`,
|
|
39
|
+
* which completes when the client closes its end. `foldkit-remote-server/port`
|
|
40
|
+
* uses it.
|
|
41
|
+
*/
|
|
42
|
+
const portRunner = (served) => {
|
|
43
|
+
const closed = Deferred.makeUnsafe();
|
|
44
|
+
return {
|
|
45
|
+
platform: { start: () => Effect.gen(function* () {
|
|
46
|
+
const disconnects = yield* Queue.make();
|
|
47
|
+
const sendUnsafe = (_, message, transfer) => served.postMessage([1, message], { transfer: [...transfer ?? []] });
|
|
48
|
+
const run = (handler) => Effect.scopedWith((scope) => Effect.gen(function* () {
|
|
49
|
+
const fork = Effect.runForkWith(yield* Effect.context());
|
|
50
|
+
const onMessage = (event) => {
|
|
51
|
+
const message = event.data;
|
|
52
|
+
if (message[0] === 1) {
|
|
53
|
+
Deferred.doneUnsafe(closed, Exit.void);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const result = handler(0, message[1]);
|
|
57
|
+
if (Effect.isEffect(result)) fork(result);
|
|
58
|
+
};
|
|
59
|
+
served.addEventListener("message", onMessage);
|
|
60
|
+
served.start();
|
|
61
|
+
served.postMessage([0]);
|
|
62
|
+
yield* Scope.addFinalizer(scope, Effect.sync(() => {
|
|
63
|
+
served.removeEventListener("message", onMessage);
|
|
64
|
+
served.close();
|
|
65
|
+
}));
|
|
66
|
+
yield* Deferred.await(closed);
|
|
67
|
+
}));
|
|
68
|
+
return {
|
|
69
|
+
run,
|
|
70
|
+
send: (portId, message, transfer) => Effect.sync(() => sendUnsafe(portId, message, transfer)),
|
|
71
|
+
sendUnsafe,
|
|
72
|
+
disconnects
|
|
73
|
+
};
|
|
74
|
+
}) },
|
|
75
|
+
closed: Deferred.await(closed)
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
//#endregion
|
|
79
|
+
export { port, portProtocol, portRunner };
|
|
80
|
+
|
|
81
|
+
//# sourceMappingURL=port.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"port.mjs","names":[],"sources":["../src/port.ts"],"sourcesContent":["/**\n * `foldkit-remote/port`: Remote over a `MessagePort`, for a server in a\n * worker or in the page (a sandbox). It speaks Effect's own RPC worker\n * protocol over the port, so reads, queries, mutations and live streams, their\n * typed errors and interruption all cross it; `foldkit-remote-server/port`\n * serves the other end.\n *\n * Built on `effect/workers` alone: a `MessagePort` platform for the client and\n * a one-port runner for the server, no browser package.\n */\nimport { Deferred, Effect, Exit, Layer, Queue, Scope } from 'effect'\nimport { RpcClient } from 'effect/rpc'\nimport * as Worker from 'effect/workers/Worker'\nimport type { WorkerError } from 'effect/workers/WorkerError'\nimport * as WorkerRunner from 'effect/workers/WorkerRunner'\nimport { Remote, type RemoteClient } from './index.js'\nimport { RemoteRpc } from './wire.js'\n\nconst platform = Worker.makePlatform<MessagePort>()({\n // Closing the client's scope tells the server the conversation is over.\n setup: ({ worker, scope }) =>\n Effect.as(\n Scope.addFinalizer(\n scope,\n Effect.sync(() => worker.postMessage([1])),\n ),\n worker,\n ),\n listen: ({ port, emit, scope }) => {\n const onMessage = (event: MessageEvent) => emit(event.data)\n port.addEventListener('message', onMessage)\n port.start()\n return Scope.addFinalizer(\n scope,\n Effect.sync(() => port.removeEventListener('message', onMessage)),\n )\n },\n})\n\n/**\n * Effect's RPC worker protocol over a `MessagePort`: what `port` runs on, for\n * an RPC client of `RemoteRpc` made by hand. `open` is called for each\n * connection the protocol makes (once, and again if it restarts), so it opens\n * a new conversation each time, such as a `MessageChannel` whose other port\n * goes to the server.\n */\nexport const portProtocol = (\n open: () => MessagePort,\n): Layer.Layer<RpcClient.Protocol, WorkerError> =>\n RpcClient.layerProtocolWorker({ size: 1 }).pipe(\n Layer.provide(\n Layer.merge(\n Layer.succeed(Worker.WorkerPlatform)(platform),\n Worker.layerSpawner(() => open()),\n ),\n ),\n )\n\n/** Remote's client over a `MessagePort`: `portProtocol` under `Remote.clientLayer`. */\nexport const port = (open: () => MessagePort): Layer.Layer<RemoteClient> =>\n Layer.unwrap(Effect.map(RpcClient.make(RemoteRpc), client => Remote.clientLayer(client))).pipe(\n Layer.provide(portProtocol(open)),\n // A port that cannot be set up is a broken sandbox, not a failed read:\n // each call's own failure is a Remote error, as over HTTP.\n Layer.orDie,\n )\n\n/**\n * The server's side of one port: Effect's `WorkerRunnerPlatform` over a single\n * `MessagePort`, for `RpcServer.layerProtocolWorkerRunner`, and `closed`,\n * which completes when the client closes its end. `foldkit-remote-server/port`\n * uses it.\n */\nexport const portRunner = (\n served: MessagePort,\n): {\n readonly platform: WorkerRunner.WorkerRunnerPlatform['Service']\n readonly closed: Effect.Effect<void>\n} => {\n const closed = Deferred.makeUnsafe<void>()\n const platform: WorkerRunner.WorkerRunnerPlatform['Service'] = {\n start: <O, I>() =>\n Effect.gen(function* () {\n const disconnects = yield* Queue.make<number>()\n const sendUnsafe = (_: number, message: O, transfer?: ReadonlyArray<unknown>) =>\n served.postMessage([1, message], {\n transfer: [...(transfer ?? [])] as Array<Transferable>,\n })\n const run = <A, E, R>(\n handler: (portId: number, message: I) => Effect.Effect<A, E, R> | void,\n ) =>\n Effect.scopedWith(scope =>\n Effect.gen(function* () {\n const fork = Effect.runForkWith(yield* Effect.context<R>())\n const onMessage = (event: MessageEvent) => {\n const message = event.data as WorkerRunner.PlatformMessage<I>\n if (message[0] === 1) {\n Deferred.doneUnsafe(closed, Exit.void)\n return\n }\n const result = handler(0, message[1])\n if (Effect.isEffect(result)) fork(result)\n }\n served.addEventListener('message', onMessage)\n served.start()\n served.postMessage([0])\n yield* Scope.addFinalizer(\n scope,\n Effect.sync(() => {\n served.removeEventListener('message', onMessage)\n served.close()\n }),\n )\n yield* Deferred.await(closed)\n }),\n )\n const runner: WorkerRunner.WorkerRunner<O, I> = {\n run,\n send: (portId, message, transfer) =>\n Effect.sync(() => sendUnsafe(portId, message, transfer)),\n sendUnsafe,\n disconnects,\n }\n return runner\n }),\n }\n return { platform, closed: Deferred.await(closed) }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAkBA,MAAM,WAAW,OAAO,aAA0B,CAAC,CAAC;CAElD,QAAQ,EAAE,QAAQ,YAChB,OAAO,GACL,MAAM,aACJ,OACA,OAAO,WAAW,OAAO,YAAY,CAAC,CAAC,CAAC,CAAC,CAC3C,GACA,MACF;CACF,SAAS,EAAE,MAAM,MAAM,YAAY;EACjC,MAAM,aAAa,UAAwB,KAAK,MAAM,IAAI;EAC1D,KAAK,iBAAiB,WAAW,SAAS;EAC1C,KAAK,MAAM;EACX,OAAO,MAAM,aACX,OACA,OAAO,WAAW,KAAK,oBAAoB,WAAW,SAAS,CAAC,CAClE;CACF;AACF,CAAC;;;;;;;;AASD,MAAa,gBACX,SAEA,UAAU,oBAAoB,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,KACzC,MAAM,QACJ,MAAM,MACJ,MAAM,QAAQ,OAAO,cAAc,CAAC,CAAC,QAAQ,GAC7C,OAAO,mBAAmB,KAAK,CAAC,CAClC,CACF,CACF;;AAGF,MAAa,QAAQ,SACnB,MAAM,OAAO,OAAO,IAAI,UAAU,KAAK,SAAS,IAAG,WAAU,OAAO,YAAY,MAAM,CAAC,CAAC,CAAC,CAAC,KACxF,MAAM,QAAQ,aAAa,IAAI,CAAC,GAGhC,MAAM,KACR;;;;;;;AAQF,MAAa,cACX,WAIG;CACH,MAAM,SAAS,SAAS,WAAiB;CA+CzC,OAAO;EAAE,UAAA,EA7CP,aACE,OAAO,IAAI,aAAa;GACtB,MAAM,cAAc,OAAO,MAAM,KAAa;GAC9C,MAAM,cAAc,GAAW,SAAY,aACzC,OAAO,YAAY,CAAC,GAAG,OAAO,GAAG,EAC/B,UAAU,CAAC,GAAI,YAAY,CAAC,CAAE,EAChC,CAAC;GACH,MAAM,OACJ,YAEA,OAAO,YAAW,UAChB,OAAO,IAAI,aAAa;IACtB,MAAM,OAAO,OAAO,YAAY,OAAO,OAAO,QAAW,CAAC;IAC1D,MAAM,aAAa,UAAwB;KACzC,MAAM,UAAU,MAAM;KACtB,IAAI,QAAQ,OAAO,GAAG;MACpB,SAAS,WAAW,QAAQ,KAAK,IAAI;MACrC;KACF;KACA,MAAM,SAAS,QAAQ,GAAG,QAAQ,EAAE;KACpC,IAAI,OAAO,SAAS,MAAM,GAAG,KAAK,MAAM;IAC1C;IACA,OAAO,iBAAiB,WAAW,SAAS;IAC5C,OAAO,MAAM;IACb,OAAO,YAAY,CAAC,CAAC,CAAC;IACtB,OAAO,MAAM,aACX,OACA,OAAO,WAAW;KAChB,OAAO,oBAAoB,WAAW,SAAS;KAC/C,OAAO,MAAM;IACf,CAAC,CACH;IACA,OAAO,SAAS,MAAM,MAAM;GAC9B,CAAC,CACH;GAQF,OAAO;IANL;IACA,OAAO,QAAQ,SAAS,aACtB,OAAO,WAAW,WAAW,QAAQ,SAAS,QAAQ,CAAC;IACzD;IACA;GAEU;EACd,CAAC,EAEW;EAAG,QAAQ,SAAS,MAAM,MAAM;CAAE;AACpD"}
|