@playfast/reform-remote 1.1.0 → 1.2.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/client.d.ts +33 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +80 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/memory.d.ts +7 -0
- package/dist/memory.d.ts.map +1 -0
- package/dist/memory.js +21 -0
- package/dist/memory.js.map +1 -0
- package/dist/react.d.ts +15 -0
- package/dist/react.d.ts.map +1 -0
- package/dist/react.js +11 -0
- package/dist/react.js.map +1 -0
- package/dist/server.d.ts +16 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +56 -0
- package/dist/server.js.map +1 -0
- package/dist/transport.d.ts +53 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +171 -0
- package/dist/transport.js.map +1 -0
- package/dist/wireNode.d.ts +24 -0
- package/dist/wireNode.d.ts.map +1 -0
- package/dist/wireNode.js +80 -0
- package/dist/wireNode.js.map +1 -0
- package/dist/wireRender.d.ts +20 -0
- package/dist/wireRender.d.ts.map +1 -0
- package/dist/wireRender.js +97 -0
- package/dist/wireRender.js.map +1 -0
- package/package.json +17 -5
- package/src/counterFixtures.ts +142 -0
- package/src/fixtures.ts +10 -453
- package/src/listFixtures.ts +174 -0
- package/src/optionalFixtures.ts +64 -0
- package/src/server.ts +11 -349
- package/src/slottedFixtures.ts +120 -0
- package/src/wireNode.ts +153 -0
- package/src/wireRender.ts +235 -0
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type MadeView, type UiContract } from '@playfast/reform';
|
|
3
|
+
import { type AnyUi, type UiReflection, type WiredUiManifest, type WireTree } from '@playfast/reform/internal';
|
|
4
|
+
export interface SlotPropsExternalApi {
|
|
5
|
+
readonly slotKey?: string;
|
|
6
|
+
}
|
|
7
|
+
export type RemoteView = (props: Record<string, unknown>, slots: Record<string, (slotProps?: SlotPropsExternalApi) => ReactNode>, events: Record<string, (payload: unknown) => void>) => ReactNode;
|
|
8
|
+
export interface RegisteredRemoteView {
|
|
9
|
+
readonly name: string;
|
|
10
|
+
readonly view: RemoteView;
|
|
11
|
+
}
|
|
12
|
+
type ViewRegistry = Readonly<Record<string, RegisteredRemoteView>>;
|
|
13
|
+
declare const ViewSetContract: unique symbol;
|
|
14
|
+
export type RemoteViewSet<C extends RemoteContract> = ViewRegistry & {
|
|
15
|
+
readonly [ViewSetContract]: (contract: C) => C;
|
|
16
|
+
};
|
|
17
|
+
type RemoteUi = UiReflection<UiContract, string> & AnyUi & {
|
|
18
|
+
readonly manifest: WiredUiManifest;
|
|
19
|
+
};
|
|
20
|
+
export type RemoteContract = Readonly<Record<string, RemoteUi>>;
|
|
21
|
+
export declare const remoteContract: <const C extends RemoteContract>(contract: C) => C;
|
|
22
|
+
type RemoteViewFor<U extends RemoteUi> = U extends UiReflection<infer Contract, infer Name> ? MadeView<Contract, Name, U> : never;
|
|
23
|
+
export type RemoteViews<C extends RemoteContract> = {
|
|
24
|
+
readonly [K in keyof C]: RemoteViewFor<C[K]>;
|
|
25
|
+
};
|
|
26
|
+
export declare const remoteViews: <C extends RemoteContract>(views: RemoteViews<C>) => RemoteViewSet<C>;
|
|
27
|
+
export interface ClientConfig<C extends RemoteContract> {
|
|
28
|
+
readonly views: RemoteViewSet<C>;
|
|
29
|
+
readonly invoke: (handle: string, payload: unknown) => void;
|
|
30
|
+
}
|
|
31
|
+
export declare const renderWireTree: <C extends RemoteContract>(tree: WireTree, config: ClientConfig<C>) => ReactNode;
|
|
32
|
+
export {};
|
|
33
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,KAAK,SAAS,EAAU,MAAM,OAAO,CAAA;AAEvE,OAAO,EAAE,KAAK,QAAQ,EAAM,KAAK,UAAU,EAAiC,MAAM,kBAAkB,CAAA;AACpG,OAAO,EAEL,KAAK,KAAK,EACV,KAAK,YAAY,EACjB,KAAK,eAAe,EAGpB,KAAK,QAAQ,EACd,MAAM,2BAA2B,CAAA;AAElC,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAC1B;AAED,MAAM,MAAM,UAAU,GAAG,CACvB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,EAAE,oBAAoB,KAAK,SAAS,CAAC,EACtE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC,KAC/C,SAAS,CAAA;AAEd,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;CAC1B;AAED,KAAK,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC,CAAA;AAElE,QAAA,MAAM,eAAe,EAAE,OAAO,MAAsD,CAAA;AAEpF,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,cAAc,IAAI,YAAY,GAAG;IACnE,QAAQ,CAAC,CAAC,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAA;CAC/C,CAAA;AAED,KAAK,QAAQ,GAAG,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,GAAG,KAAK,GAAG;IAAE,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAA;CAAE,CAAA;AACjG,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAA;AAE/D,eAAO,MAAM,cAAc,GAAI,KAAK,CAAC,CAAC,SAAS,cAAc,EAAE,UAAU,CAAC,KAAG,CAAa,CAAA;AAE1F,KAAK,aAAa,CAAC,CAAC,SAAS,QAAQ,IACnC,CAAC,SAAS,YAAY,CAAC,MAAM,QAAQ,EAAE,MAAM,IAAI,CAAC,GAAG,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,KAAK,CAAA;AAC1F,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,cAAc,IAAI;IAClD,QAAQ,EAAE,CAAC,IAAI,MAAM,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAC7C,CAAA;AAwCD,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,cAAc,EAAE,OAAO,WAAW,CAAC,CAAC,CAAC,KAAG,aAAa,CAAC,CAAC,CAS5F,CAAA;AAED,MAAM,WAAW,YAAY,CAAC,CAAC,SAAS,cAAc;IACpD,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,CAAA;IAChC,QAAQ,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;CAC5D;AAiFD,eAAO,MAAM,cAAc,GAAI,CAAC,SAAS,cAAc,EACrD,MAAM,QAAQ,EACd,QAAQ,YAAY,CAAC,CAAC,CAAC,KACtB,SAOA,CAAA"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { createElement, Fragment, useRef } from 'react';
|
|
2
|
+
import { Effect, Record as Rec, Schema } from 'effect';
|
|
3
|
+
import { Ui, UiViewContract } from '@playfast/reform';
|
|
4
|
+
import { Wire, } from '@playfast/reform/internal';
|
|
5
|
+
const ViewSetContract = Symbol.for('reform-remote/view-set-contract');
|
|
6
|
+
export const remoteContract = (contract) => contract;
|
|
7
|
+
function bindSlots(slots) {
|
|
8
|
+
return slots;
|
|
9
|
+
}
|
|
10
|
+
function bindEvents(events) {
|
|
11
|
+
return events;
|
|
12
|
+
}
|
|
13
|
+
const registerView = (view) => view.capture((exact) => {
|
|
14
|
+
const contract = exact[UiViewContract];
|
|
15
|
+
const propsReflection = contract.manifest.props;
|
|
16
|
+
if (propsReflection === undefined) {
|
|
17
|
+
return Effect.runSync(Effect.dieMessage(`reform-remote: view ${contract.manifest.name} needs a wire props schema`));
|
|
18
|
+
}
|
|
19
|
+
const propsSchema = Schema.make(propsReflection.ast);
|
|
20
|
+
return {
|
|
21
|
+
name: contract.manifest.name,
|
|
22
|
+
view: (encoded, slots, events) => exact(Schema.decodeUnknownSync(propsSchema)(encoded), bindSlots(slots), bindEvents(events)),
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
export const remoteViews = (views) => {
|
|
26
|
+
const madeViews = Object.values(views);
|
|
27
|
+
const byName = Rec.fromEntries(madeViews.map((view) => {
|
|
28
|
+
const entry = registerView(view);
|
|
29
|
+
return [entry.name, entry];
|
|
30
|
+
}));
|
|
31
|
+
return { ...byName, [ViewSetContract]: (contract) => contract };
|
|
32
|
+
};
|
|
33
|
+
const WireNodeView = ({ node, tree, config }) => {
|
|
34
|
+
// Stable slot closures read current inputs through this ref.
|
|
35
|
+
const latest = useRef({ node, tree, config });
|
|
36
|
+
latest.current = { node, tree, config };
|
|
37
|
+
// Fresh slot component types remount descendants and reset their hooks.
|
|
38
|
+
const slotCache = useRef({});
|
|
39
|
+
const registered = config.views[node.name];
|
|
40
|
+
if (registered === undefined) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
const encoded = Rec.fromEntries(node.props.flatMap((prop) => prop._tag === 'Data' ? [[prop.name, prop.value]] : []));
|
|
44
|
+
const eventEntries = node.props.flatMap((prop) => {
|
|
45
|
+
if (prop._tag !== 'Event') {
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
48
|
+
return [[prop.name, (payload) => config.invoke(prop.handle, payload)]];
|
|
49
|
+
});
|
|
50
|
+
const events = Rec.fromEntries(eventEntries);
|
|
51
|
+
// slotKey selects one wire child; omitting it renders every child in the slot.
|
|
52
|
+
const slotFor = (slotName) => {
|
|
53
|
+
const cached = slotCache.current[slotName];
|
|
54
|
+
if (cached !== undefined) {
|
|
55
|
+
return cached;
|
|
56
|
+
}
|
|
57
|
+
const stable = (slotProps) => {
|
|
58
|
+
const { node: currentNode, tree: currentTree, config: currentConfig } = latest.current;
|
|
59
|
+
const requestedKey = slotProps?.slotKey;
|
|
60
|
+
return createElement(Fragment, null, ...Wire.childrenOf(currentTree, currentNode.id)
|
|
61
|
+
.filter((child) => child.slot === slotName)
|
|
62
|
+
.filter((child) => requestedKey === undefined || child.key === requestedKey)
|
|
63
|
+
.map((child) => createElement(WireNodeView, {
|
|
64
|
+
key: child.id,
|
|
65
|
+
node: child,
|
|
66
|
+
tree: currentTree,
|
|
67
|
+
config: currentConfig,
|
|
68
|
+
})));
|
|
69
|
+
};
|
|
70
|
+
slotCache.current[slotName] = stable;
|
|
71
|
+
return stable;
|
|
72
|
+
};
|
|
73
|
+
// Empty slots must still produce a callable component, not an invalid undefined element type.
|
|
74
|
+
const slots = new Proxy(Object.create(null), {
|
|
75
|
+
get: (_target, key) => (typeof key === 'string' ? slotFor(key) : undefined),
|
|
76
|
+
});
|
|
77
|
+
return registered.view(encoded, slots, events);
|
|
78
|
+
};
|
|
79
|
+
export const renderWireTree = (tree, config) => createElement(Fragment, null, ...Wire.roots(tree).map((node) => createElement(WireNodeView, { key: node.id, node, tree, config })));
|
|
80
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * as Server from './server.js';
|
|
2
|
+
export * as Client from './client.js';
|
|
3
|
+
export * as Transport from './transport.js';
|
|
4
|
+
export * as Memory from './memory.js';
|
|
5
|
+
export * as React from './react.js';
|
|
6
|
+
export { makeRemoteServer, type RemoteServer, renderSceneToWire } from './server.js';
|
|
7
|
+
export { type ClientConfig, type RegisteredRemoteView, type RemoteContract, remoteContract, type RemoteView, type RemoteViews, type RemoteViewSet, remoteViews, renderWireTree, } from './client.js';
|
|
8
|
+
export { type ClientBinding, connect, type ConnectOptions, type InvokeMessage, type PatchesMessage, type RemoteTransport, serve, type ServeOptions, serveShared, type ServeSharedOptions, type ServerBinding, type ServerMessage, type SharedClientHandle, type SharedServerBinding, type SnapshotMessage, } from './transport.js';
|
|
9
|
+
export { inMemoryTransportPair, type TransportPair } from './memory.js';
|
|
10
|
+
export { RemoteUI, type RemoteUIProps, type StatusReporter, useConnectionStatus, useRemoteUI, } from './react.js';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,UAAU,CAAA;AAClC,OAAO,KAAK,MAAM,MAAM,UAAU,CAAA;AAClC,OAAO,KAAK,SAAS,MAAM,aAAa,CAAA;AACxC,OAAO,KAAK,MAAM,MAAM,UAAU,CAAA;AAClC,OAAO,KAAK,KAAK,MAAM,SAAS,CAAA;AAEhC,OAAO,EAAE,gBAAgB,EAAE,KAAK,YAAY,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAA;AACjF,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,cAAc,EACd,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,WAAW,EACX,cAAc,GACf,MAAM,UAAU,CAAA;AACjB,OAAO,EACL,KAAK,aAAa,EAClB,OAAO,EACP,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,EACL,KAAK,YAAY,EACjB,WAAW,EACX,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,eAAe,GACrB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,qBAAqB,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAA;AACpE,OAAO,EACL,QAAQ,EACR,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,mBAAmB,EACnB,WAAW,GACZ,MAAM,SAAS,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * as Server from './server.js';
|
|
2
|
+
export * as Client from './client.js';
|
|
3
|
+
export * as Transport from './transport.js';
|
|
4
|
+
export * as Memory from './memory.js';
|
|
5
|
+
export * as React from './react.js';
|
|
6
|
+
export { makeRemoteServer, renderSceneToWire } from './server.js';
|
|
7
|
+
export { remoteContract, remoteViews, renderWireTree, } from './client.js';
|
|
8
|
+
export { connect, serve, serveShared, } from './transport.js';
|
|
9
|
+
export { inMemoryTransportPair } from './memory.js';
|
|
10
|
+
export { RemoteUI, useConnectionStatus, useRemoteUI, } from './react.js';
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,UAAU,CAAA;AAClC,OAAO,KAAK,MAAM,MAAM,UAAU,CAAA;AAClC,OAAO,KAAK,SAAS,MAAM,aAAa,CAAA;AACxC,OAAO,KAAK,MAAM,MAAM,UAAU,CAAA;AAClC,OAAO,KAAK,KAAK,MAAM,SAAS,CAAA;AAEhC,OAAO,EAAE,gBAAgB,EAAqB,iBAAiB,EAAE,MAAM,UAAU,CAAA;AACjF,OAAO,EAIL,cAAc,EAId,WAAW,EACX,cAAc,GACf,MAAM,UAAU,CAAA;AACjB,OAAO,EAEL,OAAO,EAKP,KAAK,EAEL,WAAW,GAOZ,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,qBAAqB,EAAsB,MAAM,UAAU,CAAA;AACpE,OAAO,EACL,QAAQ,EAGR,mBAAmB,EACnB,WAAW,GACZ,MAAM,SAAS,CAAA"}
|
package/dist/memory.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { RemoteTransport } from './transport.js';
|
|
2
|
+
export interface TransportPair<Server, Client> {
|
|
3
|
+
readonly server: RemoteTransport<Server, Client>;
|
|
4
|
+
readonly client: RemoteTransport<Client, Server>;
|
|
5
|
+
}
|
|
6
|
+
export declare const inMemoryTransportPair: <Server, Client>() => TransportPair<Server, Client>;
|
|
7
|
+
//# sourceMappingURL=memory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAElD,MAAM,WAAW,aAAa,CAAC,MAAM,EAAE,MAAM;IAC3C,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChD,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACjD;AAED,eAAO,MAAM,qBAAqB,GAAI,MAAM,EAAE,MAAM,OAAK,aAAa,CAAC,MAAM,EAAE,MAAM,CAmBpF,CAAA"}
|
package/dist/memory.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export const inMemoryTransportPair = () => {
|
|
2
|
+
const serverHandlers = new Set();
|
|
3
|
+
const clientHandlers = new Set();
|
|
4
|
+
return {
|
|
5
|
+
server: {
|
|
6
|
+
send: (message) => clientHandlers.forEach((handler) => handler(message)),
|
|
7
|
+
onMessage: (handler) => {
|
|
8
|
+
serverHandlers.add(handler);
|
|
9
|
+
return () => void serverHandlers.delete(handler);
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
client: {
|
|
13
|
+
send: (message) => serverHandlers.forEach((handler) => handler(message)),
|
|
14
|
+
onMessage: (handler) => {
|
|
15
|
+
clientHandlers.add(handler);
|
|
16
|
+
return () => void clientHandlers.delete(handler);
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=memory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"AAOA,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAkD,EAAE;IACvF,MAAM,cAAc,GAAG,IAAI,GAAG,EAA6B,CAAA;IAC3D,MAAM,cAAc,GAAG,IAAI,GAAG,EAA6B,CAAA;IAC3D,OAAO;QACL,MAAM,EAAE;YACN,IAAI,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACxE,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE;gBACrB,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;gBAC3B,OAAO,GAAG,EAAE,CAAC,KAAK,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;YAClD,CAAC;SACF;QACD,MAAM,EAAE;YACN,IAAI,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACxE,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE;gBACrB,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;gBAC3B,OAAO,GAAG,EAAE,CAAC,KAAK,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;YAClD,CAAC;SACF;KACF,CAAA;AACH,CAAC,CAAA"}
|
package/dist/react.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type InvokeMessage, type RemoteTransport, type ServerMessage } from './transport.js';
|
|
3
|
+
import type { RemoteContract, RemoteViewSet } from './client.js';
|
|
4
|
+
export declare const useRemoteUI: <C extends RemoteContract>(transport: RemoteTransport<InvokeMessage, ServerMessage>, views: RemoteViewSet<C>) => ReactNode;
|
|
5
|
+
export interface RemoteUIProps<C extends RemoteContract> {
|
|
6
|
+
readonly transport: RemoteTransport<InvokeMessage, ServerMessage>;
|
|
7
|
+
readonly views: RemoteViewSet<C>;
|
|
8
|
+
}
|
|
9
|
+
export declare const RemoteUI: <C extends RemoteContract>({ transport, views, }: RemoteUIProps<C>) => ReactNode;
|
|
10
|
+
export interface StatusReporter<S> {
|
|
11
|
+
readonly status: () => S;
|
|
12
|
+
readonly onStatusChange: (listener: () => void) => () => void;
|
|
13
|
+
}
|
|
14
|
+
export declare const useConnectionStatus: <S>(reporter: StatusReporter<S>) => S;
|
|
15
|
+
//# sourceMappingURL=react.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAA6C,MAAM,OAAO,CAAA;AACjF,OAAO,EAAW,KAAK,aAAa,EAAE,KAAK,eAAe,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAA;AACnG,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAE7D,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,cAAc,EAClD,WAAW,eAAe,CAAC,aAAa,EAAE,aAAa,CAAC,EACxD,OAAO,aAAa,CAAC,CAAC,CAAC,KACtB,SAKF,CAAA;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,cAAc;IACrD,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC,aAAa,EAAE,aAAa,CAAC,CAAA;IACjE,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,CAAA;CACjC;AAED,eAAO,MAAM,QAAQ,GAAI,CAAC,SAAS,cAAc,EAAE,uBAGhD,aAAa,CAAC,CAAC,CAAC,KAAG,SAA0C,CAAA;AAEhE,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACxB,QAAQ,CAAC,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAA;CAC9D;AAED,eAAO,MAAM,mBAAmB,GAAI,CAAC,EAAE,UAAU,cAAc,CAAC,CAAC,CAAC,KAAG,CACY,CAAA"}
|
package/dist/react.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { useEffect, useState, useSyncExternalStore } from 'react';
|
|
2
|
+
import { connect } from './transport.js';
|
|
3
|
+
export const useRemoteUI = (transport, views) => {
|
|
4
|
+
const [binding] = useState(() => connect({ transport, views }));
|
|
5
|
+
useEffect(() => () => binding.dispose(), [binding]);
|
|
6
|
+
useSyncExternalStore(binding.subscribe, binding.snapshot, binding.snapshot);
|
|
7
|
+
return binding.node();
|
|
8
|
+
};
|
|
9
|
+
export const RemoteUI = ({ transport, views, }) => useRemoteUI(transport, views);
|
|
10
|
+
export const useConnectionStatus = (reporter) => useSyncExternalStore(reporter.onStatusChange, reporter.status, reporter.status);
|
|
11
|
+
//# sourceMappingURL=react.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react.js","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,SAAS,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAA;AACjF,OAAO,EAAE,OAAO,EAAgE,MAAM,aAAa,CAAA;AAGnG,MAAM,CAAC,MAAM,WAAW,GAAG,CACzB,SAAwD,EACxD,KAAuB,EACZ,EAAE;IACb,MAAM,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC,CAAA;IAC/D,SAAS,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAA;IACnD,oBAAoB,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;IAC3E,OAAO,OAAO,CAAC,IAAI,EAAE,CAAA;AACvB,CAAC,CAAA;AAOD,MAAM,CAAC,MAAM,QAAQ,GAAG,CAA2B,EACjD,SAAS,EACT,KAAK,GACY,EAAa,EAAE,CAAC,WAAW,CAAC,SAAS,EAAE,KAAK,CAAC,CAAA;AAOhE,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAI,QAA2B,EAAK,EAAE,CACvE,oBAAoB,CAAC,QAAQ,CAAC,cAAc,EAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Effect, type ParseResult } from 'effect';
|
|
2
|
+
import { type CapturedScene, type UiContract } from '@playfast/reform';
|
|
3
|
+
import { type AnyScene, type WirePatch, type WireTree } from '@playfast/reform/internal';
|
|
4
|
+
import { type RenderSceneToWireOptions } from './wireRender.js';
|
|
5
|
+
export type { RenderSceneToWireOptions } from './wireRender.js';
|
|
6
|
+
export declare const renderSceneToWire: <C extends UiContract, S extends ReadonlyArray<unknown>, Services, P, N extends string, Identity>(scene: CapturedScene<C, S, Services, P, N, Identity>, options?: RenderSceneToWireOptions) => Effect.Effect<WireTree, ParseResult.ParseError, Services>;
|
|
7
|
+
export interface RemoteServer {
|
|
8
|
+
readonly render: () => Promise<WireTree>;
|
|
9
|
+
readonly renderDiff: () => Promise<ReadonlyArray<WirePatch>>;
|
|
10
|
+
readonly invoke: (handle: string, encodedPayload: unknown) => Promise<void>;
|
|
11
|
+
readonly subscribe: (listener: () => void) => () => void;
|
|
12
|
+
readonly currentTree: () => WireTree;
|
|
13
|
+
readonly dispose: () => Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
export declare const makeRemoteServer: (scene: AnyScene) => RemoteServer;
|
|
16
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EAIN,KAAK,WAAW,EAGjB,MAAM,QAAQ,CAAA;AACf,OAAO,EAAE,KAAK,aAAa,EAAsB,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC1F,OAAO,EACL,KAAK,QAAQ,EAKb,KAAK,SAAS,EACd,KAAK,QAAQ,EACd,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAGL,KAAK,wBAAwB,EAG9B,MAAM,cAAc,CAAA;AAGrB,YAAY,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAA;AAG5D,eAAO,MAAM,iBAAiB,GAC5B,CAAC,SAAS,UAAU,EACpB,CAAC,SAAS,aAAa,CAAC,OAAO,CAAC,EAChC,QAAQ,EACR,CAAC,EACD,CAAC,SAAS,MAAM,EAChB,QAAQ,EAER,OAAO,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,EACpD,UAAU,wBAAwB,KACjC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,UAAU,EAAE,QAAQ,CAUxD,CAAA;AAEH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAA;IACxC,QAAQ,CAAC,UAAU,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAA;IAC5D,QAAQ,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3E,QAAQ,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAA;IACxD,QAAQ,CAAC,WAAW,EAAE,MAAM,QAAQ,CAAA;IACpC,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CACtC;AA2GD,eAAO,MAAM,gBAAgB,GAAI,OAAO,QAAQ,KAAG,YAYhD,CAAA"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { Effect, Layer, ManagedRuntime, Option, PubSub, Queue, } from 'effect';
|
|
2
|
+
import { forceSync, publish } from '@playfast/reform';
|
|
3
|
+
import { Bus, Triggers, Wire, } from '@playfast/reform/internal';
|
|
4
|
+
import { capturedSlotProvider, renderCapturedComposition, renderSceneWith, serviceFromContext, } from './wireRender.js';
|
|
5
|
+
import { handlesOf, settleDrain } from './wireNode.js';
|
|
6
|
+
// oxlint-disable-next-line reform-rules/prefer-effect-fn -- exported binding: Effect.fn's inferred type isn't portable under isolatedDeclarations
|
|
7
|
+
export const renderSceneToWire = (scene, options) => Effect.context().pipe(Effect.flatMap((context) => renderSceneWith(scene, options, (slotDefinition) => capturedSlotProvider(context, slotDefinition), (composition, props) => renderCapturedComposition(context, composition, props))));
|
|
8
|
+
const makeCapturedRemoteServer = (scene) => {
|
|
9
|
+
const layer = scene.provide.reduce((acc, provided) => Layer.merge(acc, provided));
|
|
10
|
+
const runtime = ManagedRuntime.make(layer);
|
|
11
|
+
const registry = forceSync(() => runtime.runSync(Triggers.make));
|
|
12
|
+
const context = forceSync(() => runtime.runSync(Effect.context()));
|
|
13
|
+
const busFromContext = serviceFromContext(context, Bus, 'reform-remote: scene does not provide Bus');
|
|
14
|
+
const renderEffect = settleDrain.pipe(Effect.zipRight(renderSceneWith(scene, { register: registry.register }, (slotDefinition) => capturedSlotProvider(context, slotDefinition), (composition, props) => renderCapturedComposition(context, composition, props))));
|
|
15
|
+
const changeListeners = new Set();
|
|
16
|
+
const notifyChange = () => {
|
|
17
|
+
changeListeners.forEach((listener) => listener());
|
|
18
|
+
};
|
|
19
|
+
runtime.runFork(Effect.scoped(Effect.gen(function* () {
|
|
20
|
+
const bus = yield* busFromContext;
|
|
21
|
+
const subscription = yield* PubSub.subscribe(bus);
|
|
22
|
+
// The transport debounces; settling here would perturb the drain's scheduling.
|
|
23
|
+
yield* Queue.take(subscription).pipe(Effect.zipRight(Effect.sync(notifyChange)), Effect.forever);
|
|
24
|
+
})));
|
|
25
|
+
runtime.runSync(Effect.forEach(Option.getOrElse(Option.fromNullable(scene.boot), () => []), (event) => busFromContext.pipe(Effect.flatMap((bus) => publish('High', event).pipe(Effect.provideService(Bus, bus))))));
|
|
26
|
+
const frame = { tree: [] };
|
|
27
|
+
const render = () => runtime.runPromise(renderEffect.pipe(Effect.tap((tree) => Effect.sync(() => {
|
|
28
|
+
frame.tree = tree;
|
|
29
|
+
}))));
|
|
30
|
+
const renderDiff = () => runtime.runPromise(Effect.gen(function* () {
|
|
31
|
+
const next = yield* renderEffect;
|
|
32
|
+
const previous = frame.tree;
|
|
33
|
+
const patches = Wire.diff(previous, next);
|
|
34
|
+
frame.tree = next;
|
|
35
|
+
const nextIds = new Set(next.map((node) => node.id));
|
|
36
|
+
const staleHandles = previous.filter((node) => !nextIds.has(node.id)).flatMap(handlesOf);
|
|
37
|
+
yield* Effect.forEach(staleHandles, (handle) => registry.revoke(handle));
|
|
38
|
+
return patches;
|
|
39
|
+
}));
|
|
40
|
+
return {
|
|
41
|
+
render,
|
|
42
|
+
renderDiff,
|
|
43
|
+
invoke: (handle, encodedPayload) => runtime.runPromise(Effect.gen(function* () {
|
|
44
|
+
yield* registry.invoke(handle, encodedPayload);
|
|
45
|
+
yield* settleDrain;
|
|
46
|
+
})),
|
|
47
|
+
subscribe: (listener) => {
|
|
48
|
+
changeListeners.add(listener);
|
|
49
|
+
return () => void changeListeners.delete(listener);
|
|
50
|
+
},
|
|
51
|
+
currentTree: () => frame.tree,
|
|
52
|
+
dispose: () => runtime.dispose(),
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
export const makeRemoteServer = (scene) => scene.captureAny((exactScene) => makeCapturedRemoteServer(exactScene));
|
|
56
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import { type AnyScene, type WirePatch, type WireTree } from '@playfast/reform/internal';
|
|
3
|
+
import { type RemoteContract, type RemoteViewSet } from './client.js';
|
|
4
|
+
export interface SnapshotMessage {
|
|
5
|
+
readonly _tag: 'Snapshot';
|
|
6
|
+
readonly tree: WireTree;
|
|
7
|
+
}
|
|
8
|
+
export interface PatchesMessage {
|
|
9
|
+
readonly _tag: 'Patches';
|
|
10
|
+
readonly patches: ReadonlyArray<WirePatch>;
|
|
11
|
+
}
|
|
12
|
+
export type ServerMessage = SnapshotMessage | PatchesMessage;
|
|
13
|
+
export interface InvokeMessage {
|
|
14
|
+
readonly _tag: 'Invoke';
|
|
15
|
+
readonly handle: string;
|
|
16
|
+
readonly payload: unknown;
|
|
17
|
+
}
|
|
18
|
+
export interface RemoteTransport<Out, In> {
|
|
19
|
+
readonly send: (message: Out) => void;
|
|
20
|
+
readonly onMessage: (handler: (message: In) => void) => () => void;
|
|
21
|
+
}
|
|
22
|
+
export interface ServerBinding {
|
|
23
|
+
readonly start: () => Promise<void>;
|
|
24
|
+
readonly dispose: () => Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
export interface ServeOptions {
|
|
27
|
+
readonly scene: AnyScene;
|
|
28
|
+
readonly transport: RemoteTransport<ServerMessage, InvokeMessage>;
|
|
29
|
+
}
|
|
30
|
+
export declare const serve: (options: ServeOptions) => ServerBinding;
|
|
31
|
+
export interface SharedClientHandle {
|
|
32
|
+
readonly remove: () => void;
|
|
33
|
+
}
|
|
34
|
+
export interface SharedServerBinding {
|
|
35
|
+
readonly addClient: (transport: RemoteTransport<ServerMessage, InvokeMessage>) => SharedClientHandle;
|
|
36
|
+
readonly dispose: () => Promise<void>;
|
|
37
|
+
}
|
|
38
|
+
export interface ServeSharedOptions {
|
|
39
|
+
readonly scene: AnyScene;
|
|
40
|
+
}
|
|
41
|
+
export declare const serveShared: (options: ServeSharedOptions) => SharedServerBinding;
|
|
42
|
+
export interface ClientBinding {
|
|
43
|
+
readonly node: () => ReactNode;
|
|
44
|
+
readonly subscribe: (listener: () => void) => () => void;
|
|
45
|
+
readonly snapshot: () => WireTree;
|
|
46
|
+
readonly dispose: () => void;
|
|
47
|
+
}
|
|
48
|
+
export interface ConnectOptions<C extends RemoteContract> {
|
|
49
|
+
readonly transport: RemoteTransport<InvokeMessage, ServerMessage>;
|
|
50
|
+
readonly views: RemoteViewSet<C>;
|
|
51
|
+
}
|
|
52
|
+
export declare const connect: <C extends RemoteContract>(options: ConnectOptions<C>) => ClientBinding;
|
|
53
|
+
//# sourceMappingURL=transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,EAAE,KAAK,QAAQ,EAAQ,KAAK,SAAS,EAAE,KAAK,QAAQ,EAAE,MAAM,2BAA2B,CAAA;AAE9F,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,UAAU,CAAA;AAEjB,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;IACzB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IACxB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,CAAA;CAC3C;AAED,MAAM,MAAM,aAAa,GAAG,eAAe,GAAG,cAAc,CAAA;AAE5D,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAC1B;AAED,MAAM,WAAW,eAAe,CAAC,GAAG,EAAE,EAAE;IACtC,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,CAAA;IACrC,QAAQ,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,EAAE,KAAK,IAAI,KAAK,MAAM,IAAI,CAAA;CACnE;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACnC,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CACtC;AAID,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAA;IACxB,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC,aAAa,EAAE,aAAa,CAAC,CAAA;CAClE;AAED,eAAO,MAAM,KAAK,GAAI,SAAS,YAAY,KAAG,aA+E7C,CAAA;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,IAAI,CAAA;CAC5B;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,SAAS,EAAE,CAClB,SAAS,EAAE,eAAe,CAAC,aAAa,EAAE,aAAa,CAAC,KACrD,kBAAkB,CAAA;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CACtC;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAA;CACzB;AAED,eAAO,MAAM,WAAW,GAAI,SAAS,kBAAkB,KAAG,mBA4GzD,CAAA;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,SAAS,CAAA;IAC9B,QAAQ,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAA;IACxD,QAAQ,CAAC,QAAQ,EAAE,MAAM,QAAQ,CAAA;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAA;CAC7B;AAED,MAAM,WAAW,cAAc,CAAC,CAAC,SAAS,cAAc;IACtD,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC,aAAa,EAAE,aAAa,CAAC,CAAA;IACjE,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,CAAA;CACjC;AAED,eAAO,MAAM,OAAO,GAAI,CAAC,SAAS,cAAc,EAAE,SAAS,cAAc,CAAC,CAAC,CAAC,KAAG,aAyB9E,CAAA"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { Effect, Fiber, Match, Option } from 'effect';
|
|
2
|
+
import { Wire } from '@playfast/reform/internal';
|
|
3
|
+
import { makeRemoteServer } from './server.js';
|
|
4
|
+
import { renderWireTree, } from './client.js';
|
|
5
|
+
const BACKGROUND_FLUSH_MS = 16;
|
|
6
|
+
export const serve = (options) => {
|
|
7
|
+
const { scene, transport } = options;
|
|
8
|
+
const server = makeRemoteServer(scene);
|
|
9
|
+
// Snapshot gates diffs; single-flight rendering protects the shared frame baseline.
|
|
10
|
+
const started = { value: false };
|
|
11
|
+
const flight = { promise: Option.none(), dirty: false };
|
|
12
|
+
const push = () => {
|
|
13
|
+
if (!started.value) {
|
|
14
|
+
return Effect.runPromise(Effect.void);
|
|
15
|
+
}
|
|
16
|
+
if (Option.isSome(flight.promise)) {
|
|
17
|
+
flight.dirty = true;
|
|
18
|
+
return flight.promise.value;
|
|
19
|
+
}
|
|
20
|
+
// ensuring clears the single-flight slot even when rendering fails.
|
|
21
|
+
const run = Effect.runPromise(Effect.gen(function* () {
|
|
22
|
+
const patches = yield* Effect.promise(() => server.renderDiff());
|
|
23
|
+
if (patches.length > 0) {
|
|
24
|
+
transport.send({ _tag: 'Patches', patches });
|
|
25
|
+
}
|
|
26
|
+
}).pipe(Effect.ensuring(Effect.sync(() => {
|
|
27
|
+
flight.promise = Option.none();
|
|
28
|
+
if (flight.dirty) {
|
|
29
|
+
flight.dirty = false;
|
|
30
|
+
void push();
|
|
31
|
+
}
|
|
32
|
+
}))));
|
|
33
|
+
flight.promise = Option.some(run);
|
|
34
|
+
return run;
|
|
35
|
+
};
|
|
36
|
+
// Background debounce lets the drain settle and coalesces bursts without delaying invokes.
|
|
37
|
+
const debounce = { fiber: Option.none() };
|
|
38
|
+
const scheduleFlush = () => {
|
|
39
|
+
if (!started.value || Option.isSome(debounce.fiber)) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const fiber = Effect.runFork(Effect.sleep(BACKGROUND_FLUSH_MS).pipe(Effect.zipRight(Effect.sync(() => {
|
|
43
|
+
debounce.fiber = Option.none();
|
|
44
|
+
void push();
|
|
45
|
+
}))));
|
|
46
|
+
debounce.fiber = Option.some(fiber);
|
|
47
|
+
};
|
|
48
|
+
const start = async () => {
|
|
49
|
+
const tree = await server.render();
|
|
50
|
+
transport.send({ _tag: 'Snapshot', tree });
|
|
51
|
+
started.value = true;
|
|
52
|
+
scheduleFlush();
|
|
53
|
+
};
|
|
54
|
+
const off = transport.onMessage((message) => {
|
|
55
|
+
void Effect.runPromise(Effect.promise(() => server.invoke(message.handle, message.payload)).pipe(Effect.zipRight(Effect.promise(push))));
|
|
56
|
+
});
|
|
57
|
+
const offChange = server.subscribe(scheduleFlush);
|
|
58
|
+
return {
|
|
59
|
+
start,
|
|
60
|
+
dispose: async () => {
|
|
61
|
+
off();
|
|
62
|
+
offChange();
|
|
63
|
+
if (Option.isSome(debounce.fiber)) {
|
|
64
|
+
Effect.runFork(Fiber.interrupt(debounce.fiber.value));
|
|
65
|
+
}
|
|
66
|
+
await server.dispose();
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
export const serveShared = (options) => {
|
|
71
|
+
const { scene } = options;
|
|
72
|
+
const server = makeRemoteServer(scene);
|
|
73
|
+
const clients = new Set();
|
|
74
|
+
const broadcast = (message) => {
|
|
75
|
+
clients.forEach((client) => client.send(message));
|
|
76
|
+
};
|
|
77
|
+
// One shared render baseline requires the same single-flight discipline as serve.
|
|
78
|
+
const started = { value: false };
|
|
79
|
+
const flight = { promise: Option.none(), dirty: false };
|
|
80
|
+
const push = () => {
|
|
81
|
+
if (!started.value) {
|
|
82
|
+
return Effect.runPromise(Effect.void);
|
|
83
|
+
}
|
|
84
|
+
if (Option.isSome(flight.promise)) {
|
|
85
|
+
flight.dirty = true;
|
|
86
|
+
return flight.promise.value;
|
|
87
|
+
}
|
|
88
|
+
const run = Effect.runPromise(Effect.gen(function* () {
|
|
89
|
+
const patches = yield* Effect.promise(() => server.renderDiff());
|
|
90
|
+
if (patches.length > 0) {
|
|
91
|
+
broadcast({ _tag: 'Patches', patches });
|
|
92
|
+
}
|
|
93
|
+
}).pipe(Effect.ensuring(Effect.sync(() => {
|
|
94
|
+
flight.promise = Option.none();
|
|
95
|
+
if (flight.dirty) {
|
|
96
|
+
flight.dirty = false;
|
|
97
|
+
void push();
|
|
98
|
+
}
|
|
99
|
+
}))));
|
|
100
|
+
flight.promise = Option.some(run);
|
|
101
|
+
return run;
|
|
102
|
+
};
|
|
103
|
+
const debounce = { fiber: Option.none() };
|
|
104
|
+
const scheduleFlush = () => {
|
|
105
|
+
if (!started.value || Option.isSome(debounce.fiber)) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const fiber = Effect.runFork(Effect.sleep(BACKGROUND_FLUSH_MS).pipe(Effect.zipRight(Effect.sync(() => {
|
|
109
|
+
debounce.fiber = Option.none();
|
|
110
|
+
void push();
|
|
111
|
+
}))));
|
|
112
|
+
debounce.fiber = Option.some(fiber);
|
|
113
|
+
};
|
|
114
|
+
// Clients await the initial baseline so none snapshot an empty tree.
|
|
115
|
+
const ready = (async () => {
|
|
116
|
+
await server.render();
|
|
117
|
+
started.value = true;
|
|
118
|
+
scheduleFlush();
|
|
119
|
+
})();
|
|
120
|
+
const offChange = server.subscribe(scheduleFlush);
|
|
121
|
+
const addClient = (transport) => {
|
|
122
|
+
const off = transport.onMessage((message) => {
|
|
123
|
+
void Effect.runPromise(Effect.promise(() => server.invoke(message.handle, message.payload)).pipe(Effect.zipRight(Effect.promise(push))));
|
|
124
|
+
});
|
|
125
|
+
// Snapshot and broadcast membership must change in one tick so no diff interleaves.
|
|
126
|
+
void Effect.runPromise(Effect.promise(() => ready).pipe(Effect.zipRight(Effect.sync(() => {
|
|
127
|
+
transport.send({ _tag: 'Snapshot', tree: server.currentTree() });
|
|
128
|
+
clients.add(transport);
|
|
129
|
+
}))));
|
|
130
|
+
return {
|
|
131
|
+
remove: () => {
|
|
132
|
+
off();
|
|
133
|
+
clients.delete(transport);
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
return {
|
|
138
|
+
addClient,
|
|
139
|
+
dispose: async () => {
|
|
140
|
+
offChange();
|
|
141
|
+
if (Option.isSome(debounce.fiber)) {
|
|
142
|
+
Effect.runFork(Fiber.interrupt(debounce.fiber.value));
|
|
143
|
+
}
|
|
144
|
+
clients.clear();
|
|
145
|
+
await server.dispose();
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
export const connect = (options) => {
|
|
150
|
+
const { transport, views } = options;
|
|
151
|
+
const state = { tree: [] };
|
|
152
|
+
const listeners = new Set();
|
|
153
|
+
const config = {
|
|
154
|
+
views,
|
|
155
|
+
invoke: (handle, payload) => transport.send({ _tag: 'Invoke', handle, payload }),
|
|
156
|
+
};
|
|
157
|
+
const off = transport.onMessage((message) => {
|
|
158
|
+
state.tree = Match.value(message).pipe(Match.tag('Snapshot', ({ tree }) => tree), Match.tag('Patches', ({ patches }) => Wire.apply(state.tree, patches)), Match.exhaustive);
|
|
159
|
+
listeners.forEach((listener) => listener());
|
|
160
|
+
});
|
|
161
|
+
return {
|
|
162
|
+
node: () => renderWireTree(state.tree, config),
|
|
163
|
+
subscribe: (listener) => {
|
|
164
|
+
listeners.add(listener);
|
|
165
|
+
return () => void listeners.delete(listener);
|
|
166
|
+
},
|
|
167
|
+
snapshot: () => state.tree,
|
|
168
|
+
dispose: off,
|
|
169
|
+
};
|
|
170
|
+
};
|
|
171
|
+
//# sourceMappingURL=transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Effect, Option, type ParseResult } from 'effect';
|
|
2
|
+
import { type SlotFill, type Structure, type Trigger, type UiContract } from '@playfast/reform';
|
|
3
|
+
import { type AnyComposition, type AnySlot, type AnySlotChild, type TriggerRegistryApi, type WireNode } from '@playfast/reform/internal';
|
|
4
|
+
export declare const SETTLE_DRAIN = 30;
|
|
5
|
+
export declare const settleDrain: Effect.Effect<void>;
|
|
6
|
+
export declare const eventsOf: (structure: Structure<UiContract>) => Record<string, Trigger<unknown>>;
|
|
7
|
+
export interface Mounted {
|
|
8
|
+
readonly comp: AnyComposition;
|
|
9
|
+
readonly props: unknown;
|
|
10
|
+
readonly id: string;
|
|
11
|
+
readonly parentId: Option.Option<string>;
|
|
12
|
+
readonly slot: Option.Option<string>;
|
|
13
|
+
readonly childIndex: number;
|
|
14
|
+
readonly key: Option.Option<string>;
|
|
15
|
+
}
|
|
16
|
+
export declare const childComposition: (child: AnySlotChild) => AnyComposition;
|
|
17
|
+
export declare const isRecord: (candidate: unknown) => candidate is Record<string, unknown>;
|
|
18
|
+
export declare const handlesOf: (node: WireNode) => ReadonlyArray<string>;
|
|
19
|
+
export declare const noRegister: TriggerRegistryApi['register'];
|
|
20
|
+
export declare const toWireNodeFromStructure: (mounted: Mounted, structure: Structure<UiContract>, register: TriggerRegistryApi['register']) => Effect.Effect<WireNode, ParseResult.ParseError>;
|
|
21
|
+
export declare const isSlotFill: (candidate: unknown) => candidate is SlotFill<unknown>;
|
|
22
|
+
export declare const structureFills: (structure: Structure<UiContract>) => Record<string, SlotFill<unknown>>;
|
|
23
|
+
export declare const slotsOf: (comp: AnyComposition) => Record<string, AnySlot>;
|
|
24
|
+
//# sourceMappingURL=wireNode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wireNode.d.ts","sourceRoot":"","sources":["../src/wireNode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,MAAM,EAAE,MAAM,EAAE,KAAK,WAAW,EAAyB,MAAM,QAAQ,CAAA;AAC9F,OAAO,EAGL,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,OAAO,EACZ,KAAK,UAAU,EAChB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,OAAO,EACZ,KAAK,YAAY,EACjB,KAAK,kBAAkB,EAEvB,KAAK,QAAQ,EAEd,MAAM,2BAA2B,CAAA;AAElC,eAAO,MAAM,YAAY,KAAK,CAAA;AAC9B,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAwD,CAAA;AAGpG,eAAO,MAAM,QAAQ,GAAI,WAAW,SAAS,CAAC,UAAU,CAAC,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,CAIvF,CAAA;AAEJ,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAA;IAC7B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;CACpC;AAED,eAAO,MAAM,gBAAgB,GAAI,OAAO,YAAY,KAAG,cAKtD,CAAA;AAED,eAAO,MAAM,QAAQ,GAAI,WAAW,OAAO,KAAG,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CACC,CAAA;AAElF,eAAO,MAAM,SAAS,GAAI,MAAM,QAAQ,KAAG,aAAa,CAAC,MAAM,CACa,CAAA;AAG5E,eAAO,MAAM,UAAU,EAAE,kBAAkB,CAAC,UAAU,CAAqB,CAAA;AAE3E,eAAO,MAAM,uBAAuB,EAAE,CACpC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,SAAS,CAAC,UAAU,CAAC,EAChC,QAAQ,EAAE,kBAAkB,CAAC,UAAU,CAAC,KACrC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,UAAU,CA6DjD,CAAA;AAGF,eAAO,MAAM,UAAU,GAAI,WAAW,OAAO,KAAG,SAAS,IAAI,QAAQ,CAAC,OAAO,CAIW,CAAA;AAExF,eAAO,MAAM,cAAc,GAAI,WAAW,SAAS,CAAC,UAAU,CAAC,KAAG,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,CAM/F,CAAA;AAEH,eAAO,MAAM,OAAO,GAAI,MAAM,cAAc,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAejE,CAAA"}
|