@nice-code/action 0.19.0 → 0.20.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 +699 -666
- package/build/{ActionDevtoolsCore-CCZXQBAo.d.cts → ActionDevtoolsCore-D_JvgPmz.d.mts} +2 -2
- package/build/{ActionDevtoolsCore-bjYQ8O2_.d.mts → ActionDevtoolsCore-dV-IVPcP.d.cts} +2 -2
- package/build/{ActionPayload.types-Bmkzw2df.d.mts → ActionPayload.types-CnfWlkA1.d.cts} +161 -106
- package/build/{ActionPayload.types-CdHOGGZK.d.cts → ActionPayload.types-D0DM-g65.d.mts} +161 -106
- package/build/devtools/browser/index.d.cts +1 -1
- package/build/devtools/browser/index.d.mts +1 -1
- package/build/devtools/server/index.d.cts +1 -1
- package/build/devtools/server/index.d.mts +1 -1
- package/build/index.cjs +147 -138
- package/build/index.cjs.map +1 -1
- package/build/index.d.cts +2 -2
- package/build/index.d.mts +2 -2
- package/build/index.mjs +147 -138
- package/build/index.mjs.map +1 -1
- package/build/platform/cloudflare/index.cjs +8 -4
- package/build/platform/cloudflare/index.cjs.map +1 -1
- package/build/platform/cloudflare/index.d.cts +8 -3
- package/build/platform/cloudflare/index.d.mts +8 -3
- package/build/platform/cloudflare/index.mjs +8 -4
- package/build/platform/cloudflare/index.mjs.map +1 -1
- package/build/react-query/index.d.cts +1 -1
- package/build/react-query/index.d.mts +1 -1
- package/build/{wsAcceptorCarrier-DHRbsY1X.cjs → wsAcceptorCarrier-BDJRIPfu.cjs} +2 -2
- package/build/wsAcceptorCarrier-BDJRIPfu.cjs.map +1 -0
- package/build/{wsAcceptorCarrier-CXGlQU_f.mjs → wsAcceptorCarrier-CW2qX25W.mjs} +2 -2
- package/build/wsAcceptorCarrier-CW2qX25W.mjs.map +1 -0
- package/package.json +4 -4
- package/build/wsAcceptorCarrier-CXGlQU_f.mjs.map +0 -1
- package/build/wsAcceptorCarrier-DHRbsY1X.cjs.map +0 -1
package/build/index.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_rolldown_runtime = require("./rolldown-runtime-emK7D4bc.cjs");
|
|
3
3
|
const require_RunningAction_types = require("./RunningAction.types-DjCX1xp5.cjs");
|
|
4
|
-
const require_wsAcceptorCarrier = require("./wsAcceptorCarrier-
|
|
4
|
+
const require_wsAcceptorCarrier = require("./wsAcceptorCarrier-BDJRIPfu.cjs");
|
|
5
5
|
let nanoid = require("nanoid");
|
|
6
6
|
let _nice_code_error = require("@nice-code/error");
|
|
7
7
|
let _nice_code_common_errors = require("@nice-code/common-errors");
|
|
@@ -3538,6 +3538,113 @@ function createActionFetchHandler(runtime, options = {}) {
|
|
|
3538
3538
|
};
|
|
3539
3539
|
}
|
|
3540
3540
|
//#endregion
|
|
3541
|
+
//#region src/ActionRuntime/Handler/PeerLink/Acceptor/Hibernation/ConnectionStateStore.ts
|
|
3542
|
+
/**
|
|
3543
|
+
* A typed per-connection state store that co-owns the app state and the acceptor handler's routing
|
|
3544
|
+
* binding in one attachment, so neither the consumer nor the handler has to hand-merge the two. Create
|
|
3545
|
+
* it through {@link createConnectionStateStore} (which also wires binding persistence and replays
|
|
3546
|
+
* surviving connections after a wake), then `get`/`set`/`clearApp` the app state directly.
|
|
3547
|
+
*
|
|
3548
|
+
* The mechanism is carrier-neutral — it only needs read/write/enumerate callbacks for the connection's
|
|
3549
|
+
* attachment — but it pays off on transports whose connections outlive process eviction (e.g. a
|
|
3550
|
+
* Durable Object's hibernatable WebSockets), which is why it lives beside the hibernation adapter.
|
|
3551
|
+
*
|
|
3552
|
+
* ```ts
|
|
3553
|
+
* const players = createConnectionStateStore(serverHandler, {
|
|
3554
|
+
* schema: vs_player,
|
|
3555
|
+
* read: (ws) => ws.deserializeAttachment(),
|
|
3556
|
+
* write: (ws, v) => ws.serializeAttachment(v),
|
|
3557
|
+
* getConnections: () => ctx.getWebSockets(),
|
|
3558
|
+
* });
|
|
3559
|
+
* players.set(ws, player); // binding is preserved automatically
|
|
3560
|
+
* const player = players.get(ws);
|
|
3561
|
+
* ```
|
|
3562
|
+
*/
|
|
3563
|
+
var ConnectionStateStore = class {
|
|
3564
|
+
options;
|
|
3565
|
+
constructor(options) {
|
|
3566
|
+
this.options = options;
|
|
3567
|
+
}
|
|
3568
|
+
/** The validated app state for a connection, or `null` if unset / invalid. */
|
|
3569
|
+
get(connection) {
|
|
3570
|
+
return this._readAttachment(connection).app ?? null;
|
|
3571
|
+
}
|
|
3572
|
+
/** Set the app state, preserving the runtime binding already pinned to the connection. */
|
|
3573
|
+
set(connection, app) {
|
|
3574
|
+
const existing = this._readAttachment(connection);
|
|
3575
|
+
this.options.write(connection, {
|
|
3576
|
+
app,
|
|
3577
|
+
binding: existing.binding
|
|
3578
|
+
});
|
|
3579
|
+
}
|
|
3580
|
+
/** Clear the app state but keep the binding (e.g. a spectator that stopped watching). */
|
|
3581
|
+
clearApp(connection) {
|
|
3582
|
+
const existing = this._readAttachment(connection);
|
|
3583
|
+
this.options.write(connection, { binding: existing.binding });
|
|
3584
|
+
}
|
|
3585
|
+
/** Every live connection paired with its (validated) app state — for rebuilding in-memory state after a wake. */
|
|
3586
|
+
entries() {
|
|
3587
|
+
return this.options.getConnections().map((connection) => [connection, this._readAttachment(connection).app ?? null]);
|
|
3588
|
+
}
|
|
3589
|
+
/** @internal Persist a freshly-bound connection's binding, preserving any app state already stored. */
|
|
3590
|
+
_persistBinding(connection, binding) {
|
|
3591
|
+
const existing = this._readAttachment(connection);
|
|
3592
|
+
this.options.write(connection, {
|
|
3593
|
+
app: existing.app,
|
|
3594
|
+
binding
|
|
3595
|
+
});
|
|
3596
|
+
}
|
|
3597
|
+
/** @internal The persisted binding for a connection, if any (used to replay routing after a wake). */
|
|
3598
|
+
_readBinding(connection) {
|
|
3599
|
+
return this._readAttachment(connection).binding;
|
|
3600
|
+
}
|
|
3601
|
+
_readAttachment(connection) {
|
|
3602
|
+
try {
|
|
3603
|
+
const raw = this.options.read(connection);
|
|
3604
|
+
if (typeof raw !== "object" || raw === null) return {};
|
|
3605
|
+
const attachment = raw;
|
|
3606
|
+
const result = {};
|
|
3607
|
+
if (attachment.binding != null) result.binding = attachment.binding;
|
|
3608
|
+
if (attachment.app !== void 0) {
|
|
3609
|
+
const app = this._validateApp(attachment.app);
|
|
3610
|
+
if (app !== void 0) result.app = app;
|
|
3611
|
+
}
|
|
3612
|
+
return result;
|
|
3613
|
+
} catch {
|
|
3614
|
+
return {};
|
|
3615
|
+
}
|
|
3616
|
+
}
|
|
3617
|
+
_validateApp(value) {
|
|
3618
|
+
const schema = this.options.schema;
|
|
3619
|
+
if (schema == null) return value;
|
|
3620
|
+
const result = schema["~standard"].validate(value);
|
|
3621
|
+
if (result instanceof Promise) return void 0;
|
|
3622
|
+
if (result.issues != null) return void 0;
|
|
3623
|
+
return result.value;
|
|
3624
|
+
}
|
|
3625
|
+
};
|
|
3626
|
+
/**
|
|
3627
|
+
* Build a per-connection {@link ConnectionStateStore} bound to an {@link AcceptorHandler}: it registers
|
|
3628
|
+
* itself as the handler's connection-bound persistence callback (so bindings are written without
|
|
3629
|
+
* overwriting app state) and immediately replays every live connection's stored binding via
|
|
3630
|
+
* {@link AcceptorHandler.rehydrateConnection} — so on a transport that resumes after eviction (e.g. a
|
|
3631
|
+
* Durable Object waking from hibernation) both the app identity and the action routing come back from a
|
|
3632
|
+
* single attachment, with no storage reads and no hand-rolled merge.
|
|
3633
|
+
*
|
|
3634
|
+
* Lives outside the handler so the generic {@link AcceptorHandler} stays free of any attachment/
|
|
3635
|
+
* hibernation concern — it exposes only the neutral `setOnConnectionBound` + `rehydrateConnection`
|
|
3636
|
+
* hooks this builder drives.
|
|
3637
|
+
*/
|
|
3638
|
+
function createConnectionStateStore(handler, options) {
|
|
3639
|
+
const store = new ConnectionStateStore(options);
|
|
3640
|
+
handler.setOnConnectionBound((connection, binding) => store._persistBinding(connection, binding));
|
|
3641
|
+
for (const connection of options.getConnections()) {
|
|
3642
|
+
const binding = store._readBinding(connection);
|
|
3643
|
+
if (binding != null) handler.rehydrateConnection(connection, binding);
|
|
3644
|
+
}
|
|
3645
|
+
return store;
|
|
3646
|
+
}
|
|
3647
|
+
//#endregion
|
|
3541
3648
|
//#region src/ActionRuntime/Handler/PeerLink/Acceptor/Hibernation/createHibernatableWsServerAdapter.ts
|
|
3542
3649
|
/**
|
|
3543
3650
|
* Wire the hibernation lifecycle for an acceptor handler on a transport whose connections outlive process
|
|
@@ -3576,34 +3683,14 @@ const DEFAULT_SERVER_SECURITY_LEVELS = [
|
|
|
3576
3683
|
"authenticated",
|
|
3577
3684
|
"encrypted"
|
|
3578
3685
|
];
|
|
3579
|
-
/**
|
|
3580
|
-
* Serve a secure channel over one or more carriers from a single call — the accept-in dual of
|
|
3581
|
-
* `connectChannel`. It builds the crypto identity (a {@link ClientCryptoKeyLink} + a storage-backed TOFU
|
|
3582
|
-
* resolver) and the security block (coordinate, dictionary version, accepted levels) *once* from
|
|
3583
|
-
* `(runtime, channel)` and fans them across every carrier, so the WebSocket and the secure-HTTP endpoint
|
|
3584
|
-
* can never drift apart. It registers your handlers (plus the duplex acceptor it builds) on the runtime,
|
|
3585
|
-
* wires hibernation when the duplex carrier declares it, and returns a single {@link IChannelServer} whose
|
|
3586
|
-
* `fetch` / `duplex` / `pushToClient` you forward straight to the host:
|
|
3587
|
-
* ```ts
|
|
3588
|
-
* const server = serveChannel(runtime, channel, {
|
|
3589
|
-
* clientEnv, storage,
|
|
3590
|
-
* carriers: [wsAcceptorCarrier({ send, upgrade, hibernation }), httpAcceptorCarrier()],
|
|
3591
|
-
* handlers: [localHandler],
|
|
3592
|
-
* });
|
|
3593
|
-
* // fetch(req) => server.fetch(req)
|
|
3594
|
-
* // webSocketMessage(conn, m) => server.duplex?.receive(conn, m)
|
|
3595
|
-
* // webSocketClose/Error(conn) => server.duplex?.drop(conn)
|
|
3596
|
-
* ```
|
|
3597
|
-
*
|
|
3598
|
-
* `TConn` (the live-connection token a duplex carrier hands back through `send`/`receive`/`drop`) is
|
|
3599
|
-
* inferred from the carriers — `WebSocket` for `wsAcceptorCarrier`, the data-channel type for a WebRTC
|
|
3600
|
-
* carrier, and so on — so it stays carrier-agnostic.
|
|
3601
|
-
*/
|
|
3602
3686
|
function serveChannel(runtime, channel, options) {
|
|
3603
3687
|
const duplexCarriers = options.carriers.filter((carrier) => !require_wsAcceptorCarrier.isExchangeAcceptorCarrier(carrier));
|
|
3604
3688
|
const exchangeCarriers = options.carriers.filter(require_wsAcceptorCarrier.isExchangeAcceptorCarrier);
|
|
3605
3689
|
if (exchangeCarriers.length > 1) throw new Error("serveChannel: at most one exchange carrier is supported");
|
|
3606
3690
|
const exchangeCarrier = exchangeCarriers[0];
|
|
3691
|
+
const singleDuplex = duplexCarriers.length === 1;
|
|
3692
|
+
if (options.connectionState != null && !singleDuplex) throw new Error("serveChannel: `connectionState` requires exactly one duplex carrier");
|
|
3693
|
+
if (options.channelCases != null && !singleDuplex) throw new Error("serveChannel: `channelCases` requires exactly one duplex carrier");
|
|
3607
3694
|
const exchangeSecure = exchangeCarrier != null && (exchangeCarrier.secure ?? true);
|
|
3608
3695
|
const anyDuplexSecure = duplexCarriers.some((carrier) => carrier.secure ?? true);
|
|
3609
3696
|
const securityLevel = options.securityLevel ?? DEFAULT_SERVER_SECURITY_LEVELS;
|
|
@@ -3617,7 +3704,13 @@ function serveChannel(runtime, channel, options) {
|
|
|
3617
3704
|
verifyKeyResolver: options.verifyKeyResolver ?? createStorageTofuVerifyKeyResolver(storage)
|
|
3618
3705
|
};
|
|
3619
3706
|
}
|
|
3707
|
+
const plainRouter = (handler) => ({
|
|
3708
|
+
receive: (connection, frame) => handler.receive(connection, frame),
|
|
3709
|
+
drop: (connection) => handler.dropConnection(connection)
|
|
3710
|
+
});
|
|
3711
|
+
const asObject = (value) => typeof value === "object" && value != null ? value : {};
|
|
3620
3712
|
const handlers = [];
|
|
3713
|
+
let connections;
|
|
3621
3714
|
for (const carrier of duplexCarriers) {
|
|
3622
3715
|
const handler = (carrier.secure ?? true) && secure != null ? acceptChannel(runtime, channel, {
|
|
3623
3716
|
clientEnv: options.clientEnv,
|
|
@@ -3634,17 +3727,31 @@ function serveChannel(runtime, channel, options) {
|
|
|
3634
3727
|
runtime,
|
|
3635
3728
|
defaultTimeout: options.defaultTimeout
|
|
3636
3729
|
});
|
|
3637
|
-
const
|
|
3730
|
+
const attach = carrier.attachmentStore;
|
|
3731
|
+
let router;
|
|
3732
|
+
if (attach == null) router = plainRouter(handler);
|
|
3733
|
+
else if (options.connectionState != null) {
|
|
3734
|
+
connections = createConnectionStateStore(handler, {
|
|
3735
|
+
schema: options.connectionState.schema,
|
|
3736
|
+
getConnections: attach.getConnections,
|
|
3737
|
+
read: attach.read,
|
|
3738
|
+
write: attach.write
|
|
3739
|
+
});
|
|
3740
|
+
router = plainRouter(handler);
|
|
3741
|
+
} else router = createHibernatableWsServerAdapter({
|
|
3638
3742
|
handler,
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3743
|
+
getConnections: attach.getConnections,
|
|
3744
|
+
getAttachment: (connection) => attach.read(connection)?.binding,
|
|
3745
|
+
setAttachment: (connection, binding) => attach.write(connection, {
|
|
3746
|
+
...asObject(attach.read(connection)),
|
|
3747
|
+
binding
|
|
3748
|
+
})
|
|
3749
|
+
});
|
|
3644
3750
|
carrier._activate(router);
|
|
3645
3751
|
handlers.push(handler);
|
|
3646
3752
|
}
|
|
3647
3753
|
runtime.addHandlers([...options.handlers ?? [], ...handlers]);
|
|
3754
|
+
if (options.channelCases != null) runtime.addHandlers([acceptChannelConnections(handlers[0], channel, options.channelCases)]);
|
|
3648
3755
|
const exchangeSecurity = exchangeSecure && secure != null ? {
|
|
3649
3756
|
link: secure.link,
|
|
3650
3757
|
verifyKeyResolver: secure.verifyKeyResolver,
|
|
@@ -3675,121 +3782,23 @@ function serveChannel(runtime, channel, options) {
|
|
|
3675
3782
|
if (owner == null) throw new Error("serveChannel: no duplex carrier holds a connection for the push target");
|
|
3676
3783
|
return owner.pushToClient(runtime, target, request, pushOptions);
|
|
3677
3784
|
};
|
|
3785
|
+
const broadcast = (makeRequest, broadcastOptions) => {
|
|
3786
|
+
if (!singleDuplex) throw new Error("serveChannel: broadcast requires exactly one duplex carrier — broadcast over a specific handlers[i] instead");
|
|
3787
|
+
handlers[0].broadcast(makeRequest, {
|
|
3788
|
+
runtime,
|
|
3789
|
+
...broadcastOptions
|
|
3790
|
+
});
|
|
3791
|
+
};
|
|
3678
3792
|
return {
|
|
3679
3793
|
handlers,
|
|
3680
3794
|
fetch,
|
|
3681
3795
|
duplex,
|
|
3682
|
-
pushToClient
|
|
3796
|
+
pushToClient,
|
|
3797
|
+
broadcast,
|
|
3798
|
+
connections
|
|
3683
3799
|
};
|
|
3684
3800
|
}
|
|
3685
3801
|
//#endregion
|
|
3686
|
-
//#region src/ActionRuntime/Handler/PeerLink/Acceptor/Hibernation/ConnectionStateStore.ts
|
|
3687
|
-
/**
|
|
3688
|
-
* A typed per-connection state store that co-owns the app state and the acceptor handler's routing
|
|
3689
|
-
* binding in one attachment, so neither the consumer nor the handler has to hand-merge the two. Create
|
|
3690
|
-
* it through {@link createConnectionStateStore} (which also wires binding persistence and replays
|
|
3691
|
-
* surviving connections after a wake), then `get`/`set`/`clearApp` the app state directly.
|
|
3692
|
-
*
|
|
3693
|
-
* The mechanism is carrier-neutral — it only needs read/write/enumerate callbacks for the connection's
|
|
3694
|
-
* attachment — but it pays off on transports whose connections outlive process eviction (e.g. a
|
|
3695
|
-
* Durable Object's hibernatable WebSockets), which is why it lives beside the hibernation adapter.
|
|
3696
|
-
*
|
|
3697
|
-
* ```ts
|
|
3698
|
-
* const players = createConnectionStateStore(serverHandler, {
|
|
3699
|
-
* schema: vs_player,
|
|
3700
|
-
* read: (ws) => ws.deserializeAttachment(),
|
|
3701
|
-
* write: (ws, v) => ws.serializeAttachment(v),
|
|
3702
|
-
* getConnections: () => ctx.getWebSockets(),
|
|
3703
|
-
* });
|
|
3704
|
-
* players.set(ws, player); // binding is preserved automatically
|
|
3705
|
-
* const player = players.get(ws);
|
|
3706
|
-
* ```
|
|
3707
|
-
*/
|
|
3708
|
-
var ConnectionStateStore = class {
|
|
3709
|
-
options;
|
|
3710
|
-
constructor(options) {
|
|
3711
|
-
this.options = options;
|
|
3712
|
-
}
|
|
3713
|
-
/** The validated app state for a connection, or `null` if unset / invalid. */
|
|
3714
|
-
get(connection) {
|
|
3715
|
-
return this._readAttachment(connection).app ?? null;
|
|
3716
|
-
}
|
|
3717
|
-
/** Set the app state, preserving the runtime binding already pinned to the connection. */
|
|
3718
|
-
set(connection, app) {
|
|
3719
|
-
const existing = this._readAttachment(connection);
|
|
3720
|
-
this.options.write(connection, {
|
|
3721
|
-
app,
|
|
3722
|
-
binding: existing.binding
|
|
3723
|
-
});
|
|
3724
|
-
}
|
|
3725
|
-
/** Clear the app state but keep the binding (e.g. a spectator that stopped watching). */
|
|
3726
|
-
clearApp(connection) {
|
|
3727
|
-
const existing = this._readAttachment(connection);
|
|
3728
|
-
this.options.write(connection, { binding: existing.binding });
|
|
3729
|
-
}
|
|
3730
|
-
/** Every live connection paired with its (validated) app state — for rebuilding in-memory state after a wake. */
|
|
3731
|
-
entries() {
|
|
3732
|
-
return this.options.getConnections().map((connection) => [connection, this._readAttachment(connection).app ?? null]);
|
|
3733
|
-
}
|
|
3734
|
-
/** @internal Persist a freshly-bound connection's binding, preserving any app state already stored. */
|
|
3735
|
-
_persistBinding(connection, binding) {
|
|
3736
|
-
const existing = this._readAttachment(connection);
|
|
3737
|
-
this.options.write(connection, {
|
|
3738
|
-
app: existing.app,
|
|
3739
|
-
binding
|
|
3740
|
-
});
|
|
3741
|
-
}
|
|
3742
|
-
/** @internal The persisted binding for a connection, if any (used to replay routing after a wake). */
|
|
3743
|
-
_readBinding(connection) {
|
|
3744
|
-
return this._readAttachment(connection).binding;
|
|
3745
|
-
}
|
|
3746
|
-
_readAttachment(connection) {
|
|
3747
|
-
try {
|
|
3748
|
-
const raw = this.options.read(connection);
|
|
3749
|
-
if (typeof raw !== "object" || raw === null) return {};
|
|
3750
|
-
const attachment = raw;
|
|
3751
|
-
const result = {};
|
|
3752
|
-
if (attachment.binding != null) result.binding = attachment.binding;
|
|
3753
|
-
if (attachment.app !== void 0) {
|
|
3754
|
-
const app = this._validateApp(attachment.app);
|
|
3755
|
-
if (app !== void 0) result.app = app;
|
|
3756
|
-
}
|
|
3757
|
-
return result;
|
|
3758
|
-
} catch {
|
|
3759
|
-
return {};
|
|
3760
|
-
}
|
|
3761
|
-
}
|
|
3762
|
-
_validateApp(value) {
|
|
3763
|
-
const schema = this.options.schema;
|
|
3764
|
-
if (schema == null) return value;
|
|
3765
|
-
const result = schema["~standard"].validate(value);
|
|
3766
|
-
if (result instanceof Promise) return void 0;
|
|
3767
|
-
if (result.issues != null) return void 0;
|
|
3768
|
-
return result.value;
|
|
3769
|
-
}
|
|
3770
|
-
};
|
|
3771
|
-
/**
|
|
3772
|
-
* Build a per-connection {@link ConnectionStateStore} bound to an {@link AcceptorHandler}: it registers
|
|
3773
|
-
* itself as the handler's connection-bound persistence callback (so bindings are written without
|
|
3774
|
-
* overwriting app state) and immediately replays every live connection's stored binding via
|
|
3775
|
-
* {@link AcceptorHandler.rehydrateConnection} — so on a transport that resumes after eviction (e.g. a
|
|
3776
|
-
* Durable Object waking from hibernation) both the app identity and the action routing come back from a
|
|
3777
|
-
* single attachment, with no storage reads and no hand-rolled merge.
|
|
3778
|
-
*
|
|
3779
|
-
* Lives outside the handler so the generic {@link AcceptorHandler} stays free of any attachment/
|
|
3780
|
-
* hibernation concern — it exposes only the neutral `setOnConnectionBound` + `rehydrateConnection`
|
|
3781
|
-
* hooks this builder drives.
|
|
3782
|
-
*/
|
|
3783
|
-
function createConnectionStateStore(handler, options) {
|
|
3784
|
-
const store = new ConnectionStateStore(options);
|
|
3785
|
-
handler.setOnConnectionBound((connection, binding) => store._persistBinding(connection, binding));
|
|
3786
|
-
for (const connection of options.getConnections()) {
|
|
3787
|
-
const binding = store._readBinding(connection);
|
|
3788
|
-
if (binding != null) handler.rehydrateConnection(connection, binding);
|
|
3789
|
-
}
|
|
3790
|
-
return store;
|
|
3791
|
-
}
|
|
3792
|
-
//#endregion
|
|
3793
3802
|
//#region src/ActionRuntime/Transport/Carrier/duplex/inMemory/createInMemoryChannel.ts
|
|
3794
3803
|
/**
|
|
3795
3804
|
* Two cross-wired in-process byte channels — a loopback carrier with no socket. The client end is a
|