@derivation/rpc 0.4.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/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -3
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
package/dist/index.cjs
CHANGED
|
@@ -250,7 +250,7 @@ var ReactiveSourceAdapter = class {
|
|
|
250
250
|
}
|
|
251
251
|
get LastChange() {
|
|
252
252
|
const change = this.stream.changes.value;
|
|
253
|
-
if (
|
|
253
|
+
if (change === null) return null;
|
|
254
254
|
return this.changeIso.to(change);
|
|
255
255
|
}
|
|
256
256
|
get Stream() {
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/client-message.ts","../src/client.ts","../src/reactive-adapter.ts","../src/stream-adapter.ts"],"sourcesContent":["// Main index only exports isomorphic code that works in both browser and Node.js\nexport * from \"./client.js\";\nexport * from \"./stream-types.js\";\nexport {\n ReactiveSourceAdapter,\n ReactiveSinkAdapter,\n sink as reactiveSink,\n} from \"./reactive-adapter.js\";\nexport {\n StreamSourceAdapter,\n StreamSinkAdapter,\n sink as streamSink,\n} from \"./stream-adapter.js\";\nexport type { Transport } from \"./transport.js\";\nexport type { PresenceHandler } from \"./presence-manager.js\";\n","import { z } from \"zod\";\n\nexport const SubscribeMessageSchema = z.object({\n type: z.literal(\"subscribe\"),\n id: z.number(),\n name: z.string(),\n args: z.looseObject({}),\n});\nexport type SubscribeMessage = z.infer<typeof SubscribeMessageSchema>;\n\nexport const UnsubscribeMessageSchema = z.object({\n type: z.literal(\"unsubscribe\"),\n id: z.number(),\n});\nexport type UnsubscribeMessage = z.infer<typeof UnsubscribeMessageSchema>;\n\nexport const HeartbeatMessageSchema = z.object({\n type: z.literal(\"heartbeat\"),\n});\nexport type HeartbeatMessage = z.infer<typeof HeartbeatMessageSchema>;\n\nexport const CallMessageSchema = z.object({\n type: z.literal(\"call\"),\n id: z.number(),\n name: z.string(),\n args: z.looseObject({}),\n});\nexport type CallMessage = z.infer<typeof CallMessageSchema>;\n\nexport const PresenceMessageSchema = z.object({\n type: z.literal(\"presence\"),\n data: z.looseObject({}),\n});\nexport type PresenceMessage = z.infer<typeof PresenceMessageSchema>;\n\nexport const ClientMessageSchema = z.discriminatedUnion(\"type\", [\n SubscribeMessageSchema,\n UnsubscribeMessageSchema,\n HeartbeatMessageSchema,\n CallMessageSchema,\n PresenceMessageSchema,\n]);\nexport type ClientMessage = z.infer<typeof ClientMessageSchema>;\n\nexport function parseClientMessage(data: unknown): ClientMessage {\n return ClientMessageSchema.parse(data);\n}\n\nexport const ClientMessage = {\n subscribe: (\n id: number,\n name: string,\n args: object,\n ): SubscribeMessage => ({\n type: \"subscribe\",\n id,\n name,\n args: args as Record<string, unknown>,\n }),\n unsubscribe: (id: number): UnsubscribeMessage => ({\n type: \"unsubscribe\",\n id,\n }),\n call: (\n id: number,\n name: string,\n args: object,\n ): CallMessage => ({\n type: \"call\",\n id,\n name,\n args: args as Record<string, unknown>,\n }),\n heartbeat: (): HeartbeatMessage => ({\n type: \"heartbeat\",\n }),\n presence: (data: object): PresenceMessage => ({\n type: \"presence\",\n data: data as Record<string, unknown>,\n }),\n};\n","import { ClientMessage } from \"./client-message.js\";\nimport { ServerMessage } from \"./server-message.js\";\nimport type { Graph } from \"derivation\";\nimport type {\n Sink,\n StreamSinks,\n RPCDefinition,\n MutationResult,\n} from \"./stream-types.js\";\nimport { Transport } from \"./transport.js\";\n\nfunction changer<T extends object, I extends object>(\n sink: Sink<T, I>,\n input: WeakRef<I>,\n): (change: object) => void {\n return (change) => {\n const i = input.deref();\n if (i) {\n sink.apply(change, i);\n }\n };\n}\n\nexport class Client<Defs extends RPCDefinition> {\n private nextId = 1;\n private pendingStreams = new Map<number, (snapshot: object) => void>();\n private pendingMutations = new Map<\n number,\n (result: MutationResult<unknown>) => void\n >();\n private activeStreams = new Map<number, (change: object) => void>();\n private heartbeatTimeout: NodeJS.Timeout | undefined;\n private inactivityTimeout: NodeJS.Timeout | undefined;\n\n private registry = new FinalizationRegistry<[number, string]>(\n ([id, name]) => {\n console.log(`๐งน Stream ${id} (${name}) collected โ unsubscribing`);\n this.sendMessage(ClientMessage.unsubscribe(id));\n this.activeStreams.delete(id);\n },\n );\n\n private resetHeartbeat() {\n if (this.heartbeatTimeout) {\n clearTimeout(this.heartbeatTimeout);\n }\n\n this.heartbeatTimeout = setTimeout(() => {\n this.sendMessage(ClientMessage.heartbeat());\n }, 10_000);\n }\n\n private resetInactivity() {\n if (this.inactivityTimeout) {\n clearTimeout(this.inactivityTimeout);\n }\n\n this.inactivityTimeout = setTimeout(() => {\n this.close();\n }, 30_000);\n }\n\n constructor(\n private transport: Transport,\n private sinks: StreamSinks<Defs[\"streams\"]>,\n private graph: Graph,\n ) {\n this.transport.onMessage((data: string) => {\n const message = JSON.parse(data) as ServerMessage;\n this.handleMessage(message);\n });\n this.resetHeartbeat();\n this.resetInactivity();\n }\n\n private handleMessage(message: ServerMessage) {\n this.resetInactivity();\n\n switch (message.type) {\n case \"snapshot\": {\n console.log(`[Client] Received snapshot for stream ${message.id}`);\n const resolve = this.pendingStreams.get(message.id);\n if (resolve) {\n resolve(message.snapshot as object);\n this.pendingStreams.delete(message.id);\n }\n break;\n }\n case \"delta\": {\n const changeCount = Object.keys(message.changes).length;\n console.log(`[Client] Received delta with ${changeCount} changes for streams: ${Object.keys(message.changes).join(\", \")}`);\n for (const [idStr, change] of Object.entries(message.changes)) {\n const id = Number(idStr);\n const sink = this.activeStreams.get(id);\n\n if (sink && change && typeof change === \"object\") {\n sink(change);\n } else if (!sink) {\n console.log(`๐งน Sink ${id} GC'd โ auto-unsubscribing`);\n this.sendMessage(ClientMessage.unsubscribe(id));\n this.activeStreams.delete(id);\n }\n }\n console.log(\"[Client] Stepping graph\");\n this.graph.step();\n break;\n }\n case \"result\": {\n console.log(`[Client] Received mutation result for call ${message.id}:`, message.success ? \"success\" : \"error\");\n const resolve = this.pendingMutations.get(message.id);\n if (resolve) {\n if (message.success) {\n resolve({ success: true, value: message.value });\n } else {\n resolve({\n success: false,\n error: message.error || \"Unknown error\",\n });\n }\n this.pendingMutations.delete(message.id);\n }\n break;\n }\n case \"heartbeat\":\n console.log(\"[Client] Received heartbeat\");\n break;\n }\n }\n\n private sendMessage(message: ClientMessage) {\n this.resetHeartbeat();\n this.transport.send(JSON.stringify(message));\n }\n\n async run<Key extends keyof Defs[\"streams\"]>(\n key: Key,\n args: Defs[\"streams\"][Key][\"args\"],\n ): Promise<Defs[\"streams\"][Key][\"returnType\"]> {\n console.log(\n `Running stream ${String(key)} with args ${JSON.stringify(args)}`,\n );\n const id = this.nextId++;\n\n this.sendMessage(ClientMessage.subscribe(id, String(key), args));\n\n const snapshot = await new Promise<object>((resolve) => {\n this.pendingStreams.set(id, resolve);\n });\n\n const endpoint = this.sinks[key];\n const sinkAdapter = endpoint(snapshot);\n const { stream, input } = sinkAdapter.build();\n const inputRef = new WeakRef(input);\n this.activeStreams.set(id, changer(sinkAdapter, inputRef));\n this.registry.register(input, [id, String(key)]);\n\n return stream;\n }\n\n async call<Key extends keyof Defs[\"mutations\"]>(\n key: Key,\n args: Defs[\"mutations\"][Key][\"args\"],\n ): Promise<MutationResult<Defs[\"mutations\"][Key][\"result\"]>> {\n console.log(\n `Calling mutation ${String(key)} with args ${JSON.stringify(args)}`,\n );\n const id = this.nextId++;\n\n this.sendMessage(\n ClientMessage.call(id, String(key), args as Record<string, unknown>),\n );\n\n const result = await new Promise<\n MutationResult<Defs[\"mutations\"][Key][\"result\"]>\n >((resolve) => {\n this.pendingMutations.set(\n id,\n resolve as (result: MutationResult<unknown>) => void,\n );\n });\n\n return result;\n }\n\n close() {\n clearTimeout(this.heartbeatTimeout);\n clearTimeout(this.inactivityTimeout);\n try {\n this.transport.close();\n } catch {}\n }\n\n setPresence(value: Record<string, unknown>): void {\n this.sendMessage(ClientMessage.presence(value));\n }\n}\n","import { Graph } from \"derivation\";\nimport {\n Reactive,\n ChangeInput,\n Changes,\n OperationsBase,\n Operations,\n asBase,\n} from \"@derivation/composable\";\nimport { Source, Sink } from \"./stream-types.js\";\nimport { Iso } from \"./iso.js\";\n\nexport class ReactiveSourceAdapter<T> implements Source<Reactive<T>> {\n constructor(\n private readonly stream: Reactive<T>,\n private readonly snapshotIso: Iso<T, object>,\n private readonly changeIso: Iso<Changes<T>, object>,\n ) {}\n\n get Snapshot(): object {\n return this.snapshotIso.to(this.stream.snapshot);\n }\n\n get LastChange(): object | null {\n const change = this.stream.changes.value;\n if (asBase(this.stream.operations).isEmpty(change)) return null;\n return this.changeIso.to(change);\n }\n\n get Stream(): Reactive<T> {\n return this.stream;\n }\n}\n\nexport class ReactiveSinkAdapter<T>\n implements Sink<Reactive<T>, ChangeInput<T>>\n{\n private readonly initialValue: T;\n\n constructor(\n private readonly graph: Graph,\n snapshotIso: Iso<T, object>,\n private readonly changeIso: Iso<Changes<T>, object>,\n private readonly ops: Operations<T>,\n snapshot: object,\n ) {\n this.initialValue = snapshotIso.from(snapshot);\n }\n\n apply(change: object, input: ChangeInput<T>): void {\n input.push(this.changeIso.from(change));\n }\n\n build(): { stream: Reactive<T>; input: ChangeInput<T> } {\n const ops = this.ops;\n const input = new ChangeInput<T>(this.graph, ops);\n const stream = Reactive.create(this.graph, ops, input, this.initialValue);\n return { stream, input };\n }\n}\n\nexport function sink<T>(\n graph: Graph,\n snapshotIso: Iso<T, object>,\n changeIso: Iso<Changes<T>, object>,\n ops: Operations<T>,\n): (snapshot: object) => Sink<Reactive<T>, ChangeInput<T>> {\n return (snapshot: object) => {\n return new ReactiveSinkAdapter<T>(\n graph,\n snapshotIso,\n changeIso,\n ops,\n snapshot,\n );\n };\n}\n","import { Graph, ReactiveValue, Input, inputValue } from \"derivation\";\nimport { Source, Sink } from \"./stream-types.js\";\nimport { Iso } from \"./iso.js\";\n\nexport class StreamSourceAdapter<T extends object> implements Source<ReactiveValue<T>> {\n private readonly iso: Iso<T, object>;\n\n constructor(private readonly stream: ReactiveValue<T>, iso: Iso<T, object>) {\n this.iso = iso;\n }\n\n get Snapshot(): object {\n return this.iso.to(this.stream.value);\n }\n\n get LastChange(): object | null {\n return this.iso.to(this.stream.value);\n }\n\n get Stream(): ReactiveValue<T> {\n return this.stream;\n }\n}\n\nexport class StreamSinkAdapter<T extends object> implements Sink<Input<T>, Input<T>> {\n private readonly graph: Graph;\n private readonly iso: Iso<T, object>;\n private readonly initialValue: T;\n\n constructor(graph: Graph, iso: Iso<T, object>, snapshot: object) {\n this.graph = graph;\n this.iso = iso;\n this.initialValue = iso.from(snapshot);\n }\n\n apply(change: object, input: Input<T>): void {\n input.push(this.iso.from(change));\n }\n\n build(): { stream: Input<T>; input: Input<T> } {\n const stream = inputValue(this.graph, this.initialValue);\n return { stream, input: stream };\n }\n}\n\nexport function sink<T extends object>(graph: Graph, iso: Iso<T, object>): (snapshot: object) => Sink<Input<T>, Input<T>> {\n return (snapshot: object) => {\n return new StreamSinkAdapter<T>(graph, iso, snapshot);\n };\n}\n"],"mappings":"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","names":["sink","sink","sink"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/client-message.ts","../src/client.ts","../src/reactive-adapter.ts","../src/stream-adapter.ts"],"sourcesContent":["// Main index only exports isomorphic code that works in both browser and Node.js\nexport * from \"./client.js\";\nexport * from \"./stream-types.js\";\nexport {\n ReactiveSourceAdapter,\n ReactiveSinkAdapter,\n sink as reactiveSink,\n} from \"./reactive-adapter.js\";\nexport {\n StreamSourceAdapter,\n StreamSinkAdapter,\n sink as streamSink,\n} from \"./stream-adapter.js\";\nexport type { Transport } from \"./transport.js\";\nexport type { PresenceHandler } from \"./presence-manager.js\";\n","import { z } from \"zod\";\n\nexport const SubscribeMessageSchema = z.object({\n type: z.literal(\"subscribe\"),\n id: z.number(),\n name: z.string(),\n args: z.looseObject({}),\n});\nexport type SubscribeMessage = z.infer<typeof SubscribeMessageSchema>;\n\nexport const UnsubscribeMessageSchema = z.object({\n type: z.literal(\"unsubscribe\"),\n id: z.number(),\n});\nexport type UnsubscribeMessage = z.infer<typeof UnsubscribeMessageSchema>;\n\nexport const HeartbeatMessageSchema = z.object({\n type: z.literal(\"heartbeat\"),\n});\nexport type HeartbeatMessage = z.infer<typeof HeartbeatMessageSchema>;\n\nexport const CallMessageSchema = z.object({\n type: z.literal(\"call\"),\n id: z.number(),\n name: z.string(),\n args: z.looseObject({}),\n});\nexport type CallMessage = z.infer<typeof CallMessageSchema>;\n\nexport const PresenceMessageSchema = z.object({\n type: z.literal(\"presence\"),\n data: z.looseObject({}),\n});\nexport type PresenceMessage = z.infer<typeof PresenceMessageSchema>;\n\nexport const ClientMessageSchema = z.discriminatedUnion(\"type\", [\n SubscribeMessageSchema,\n UnsubscribeMessageSchema,\n HeartbeatMessageSchema,\n CallMessageSchema,\n PresenceMessageSchema,\n]);\nexport type ClientMessage = z.infer<typeof ClientMessageSchema>;\n\nexport function parseClientMessage(data: unknown): ClientMessage {\n return ClientMessageSchema.parse(data);\n}\n\nexport const ClientMessage = {\n subscribe: (\n id: number,\n name: string,\n args: object,\n ): SubscribeMessage => ({\n type: \"subscribe\",\n id,\n name,\n args: args as Record<string, unknown>,\n }),\n unsubscribe: (id: number): UnsubscribeMessage => ({\n type: \"unsubscribe\",\n id,\n }),\n call: (\n id: number,\n name: string,\n args: object,\n ): CallMessage => ({\n type: \"call\",\n id,\n name,\n args: args as Record<string, unknown>,\n }),\n heartbeat: (): HeartbeatMessage => ({\n type: \"heartbeat\",\n }),\n presence: (data: object): PresenceMessage => ({\n type: \"presence\",\n data: data as Record<string, unknown>,\n }),\n};\n","import { ClientMessage } from \"./client-message.js\";\nimport { ServerMessage } from \"./server-message.js\";\nimport type { Graph } from \"derivation\";\nimport type {\n Sink,\n StreamSinks,\n RPCDefinition,\n MutationResult,\n} from \"./stream-types.js\";\nimport { Transport } from \"./transport.js\";\n\nfunction changer<T extends object, I extends object>(\n sink: Sink<T, I>,\n input: WeakRef<I>,\n): (change: object) => void {\n return (change) => {\n const i = input.deref();\n if (i) {\n sink.apply(change, i);\n }\n };\n}\n\nexport class Client<Defs extends RPCDefinition> {\n private nextId = 1;\n private pendingStreams = new Map<number, (snapshot: object) => void>();\n private pendingMutations = new Map<\n number,\n (result: MutationResult<unknown>) => void\n >();\n private activeStreams = new Map<number, (change: object) => void>();\n private heartbeatTimeout: NodeJS.Timeout | undefined;\n private inactivityTimeout: NodeJS.Timeout | undefined;\n\n private registry = new FinalizationRegistry<[number, string]>(\n ([id, name]) => {\n console.log(`๐งน Stream ${id} (${name}) collected โ unsubscribing`);\n this.sendMessage(ClientMessage.unsubscribe(id));\n this.activeStreams.delete(id);\n },\n );\n\n private resetHeartbeat() {\n if (this.heartbeatTimeout) {\n clearTimeout(this.heartbeatTimeout);\n }\n\n this.heartbeatTimeout = setTimeout(() => {\n this.sendMessage(ClientMessage.heartbeat());\n }, 10_000);\n }\n\n private resetInactivity() {\n if (this.inactivityTimeout) {\n clearTimeout(this.inactivityTimeout);\n }\n\n this.inactivityTimeout = setTimeout(() => {\n this.close();\n }, 30_000);\n }\n\n constructor(\n private transport: Transport,\n private sinks: StreamSinks<Defs[\"streams\"]>,\n private graph: Graph,\n ) {\n this.transport.onMessage((data: string) => {\n const message = JSON.parse(data) as ServerMessage;\n this.handleMessage(message);\n });\n this.resetHeartbeat();\n this.resetInactivity();\n }\n\n private handleMessage(message: ServerMessage) {\n this.resetInactivity();\n\n switch (message.type) {\n case \"snapshot\": {\n console.log(`[Client] Received snapshot for stream ${message.id}`);\n const resolve = this.pendingStreams.get(message.id);\n if (resolve) {\n resolve(message.snapshot as object);\n this.pendingStreams.delete(message.id);\n }\n break;\n }\n case \"delta\": {\n const changeCount = Object.keys(message.changes).length;\n console.log(`[Client] Received delta with ${changeCount} changes for streams: ${Object.keys(message.changes).join(\", \")}`);\n for (const [idStr, change] of Object.entries(message.changes)) {\n const id = Number(idStr);\n const sink = this.activeStreams.get(id);\n\n if (sink && change && typeof change === \"object\") {\n sink(change);\n } else if (!sink) {\n console.log(`๐งน Sink ${id} GC'd โ auto-unsubscribing`);\n this.sendMessage(ClientMessage.unsubscribe(id));\n this.activeStreams.delete(id);\n }\n }\n console.log(\"[Client] Stepping graph\");\n this.graph.step();\n break;\n }\n case \"result\": {\n console.log(`[Client] Received mutation result for call ${message.id}:`, message.success ? \"success\" : \"error\");\n const resolve = this.pendingMutations.get(message.id);\n if (resolve) {\n if (message.success) {\n resolve({ success: true, value: message.value });\n } else {\n resolve({\n success: false,\n error: message.error || \"Unknown error\",\n });\n }\n this.pendingMutations.delete(message.id);\n }\n break;\n }\n case \"heartbeat\":\n console.log(\"[Client] Received heartbeat\");\n break;\n }\n }\n\n private sendMessage(message: ClientMessage) {\n this.resetHeartbeat();\n this.transport.send(JSON.stringify(message));\n }\n\n async run<Key extends keyof Defs[\"streams\"]>(\n key: Key,\n args: Defs[\"streams\"][Key][\"args\"],\n ): Promise<Defs[\"streams\"][Key][\"returnType\"]> {\n console.log(\n `Running stream ${String(key)} with args ${JSON.stringify(args)}`,\n );\n const id = this.nextId++;\n\n this.sendMessage(ClientMessage.subscribe(id, String(key), args));\n\n const snapshot = await new Promise<object>((resolve) => {\n this.pendingStreams.set(id, resolve);\n });\n\n const endpoint = this.sinks[key];\n const sinkAdapter = endpoint(snapshot);\n const { stream, input } = sinkAdapter.build();\n const inputRef = new WeakRef(input);\n this.activeStreams.set(id, changer(sinkAdapter, inputRef));\n this.registry.register(input, [id, String(key)]);\n\n return stream;\n }\n\n async call<Key extends keyof Defs[\"mutations\"]>(\n key: Key,\n args: Defs[\"mutations\"][Key][\"args\"],\n ): Promise<MutationResult<Defs[\"mutations\"][Key][\"result\"]>> {\n console.log(\n `Calling mutation ${String(key)} with args ${JSON.stringify(args)}`,\n );\n const id = this.nextId++;\n\n this.sendMessage(\n ClientMessage.call(id, String(key), args as Record<string, unknown>),\n );\n\n const result = await new Promise<\n MutationResult<Defs[\"mutations\"][Key][\"result\"]>\n >((resolve) => {\n this.pendingMutations.set(\n id,\n resolve as (result: MutationResult<unknown>) => void,\n );\n });\n\n return result;\n }\n\n close() {\n clearTimeout(this.heartbeatTimeout);\n clearTimeout(this.inactivityTimeout);\n try {\n this.transport.close();\n } catch {}\n }\n\n setPresence(value: Record<string, unknown>): void {\n this.sendMessage(ClientMessage.presence(value));\n }\n}\n","import { Graph } from \"derivation\";\nimport {\n Reactive,\n ChangeInput,\n Changes,\n OperationsBase,\n Operations,\n asBase,\n} from \"@derivation/composable\";\nimport { Source, Sink } from \"./stream-types.js\";\nimport { Iso } from \"./iso.js\";\n\nexport class ReactiveSourceAdapter<T> implements Source<Reactive<T>> {\n constructor(\n private readonly stream: Reactive<T>,\n private readonly snapshotIso: Iso<T, object>,\n private readonly changeIso: Iso<Changes<T>, object>,\n ) {}\n\n get Snapshot(): object {\n return this.snapshotIso.to(this.stream.snapshot);\n }\n\n get LastChange(): object | null {\n const change = this.stream.changes.value;\n if (change === null) return null;\n return this.changeIso.to(change);\n }\n\n get Stream(): Reactive<T> {\n return this.stream;\n }\n}\n\nexport class ReactiveSinkAdapter<T>\n implements Sink<Reactive<T>, ChangeInput<T>>\n{\n private readonly initialValue: T;\n\n constructor(\n private readonly graph: Graph,\n snapshotIso: Iso<T, object>,\n private readonly changeIso: Iso<Changes<T>, object>,\n private readonly ops: Operations<T>,\n snapshot: object,\n ) {\n this.initialValue = snapshotIso.from(snapshot);\n }\n\n apply(change: object, input: ChangeInput<T>): void {\n input.push(this.changeIso.from(change));\n }\n\n build(): { stream: Reactive<T>; input: ChangeInput<T> } {\n const ops = this.ops;\n const input = new ChangeInput<T>(this.graph, ops);\n const stream = Reactive.create(this.graph, ops, input, this.initialValue);\n return { stream, input };\n }\n}\n\nexport function sink<T>(\n graph: Graph,\n snapshotIso: Iso<T, object>,\n changeIso: Iso<Changes<T>, object>,\n ops: Operations<T>,\n): (snapshot: object) => Sink<Reactive<T>, ChangeInput<T>> {\n return (snapshot: object) => {\n return new ReactiveSinkAdapter<T>(\n graph,\n snapshotIso,\n changeIso,\n ops,\n snapshot,\n );\n };\n}\n","import { Graph, ReactiveValue, Input, inputValue } from \"derivation\";\nimport { Source, Sink } from \"./stream-types.js\";\nimport { Iso } from \"./iso.js\";\n\nexport class StreamSourceAdapter<T extends object> implements Source<ReactiveValue<T>> {\n private readonly iso: Iso<T, object>;\n\n constructor(private readonly stream: ReactiveValue<T>, iso: Iso<T, object>) {\n this.iso = iso;\n }\n\n get Snapshot(): object {\n return this.iso.to(this.stream.value);\n }\n\n get LastChange(): object | null {\n return this.iso.to(this.stream.value);\n }\n\n get Stream(): ReactiveValue<T> {\n return this.stream;\n }\n}\n\nexport class StreamSinkAdapter<T extends object> implements Sink<Input<T>, Input<T>> {\n private readonly graph: Graph;\n private readonly iso: Iso<T, object>;\n private readonly initialValue: T;\n\n constructor(graph: Graph, iso: Iso<T, object>, snapshot: object) {\n this.graph = graph;\n this.iso = iso;\n this.initialValue = iso.from(snapshot);\n }\n\n apply(change: object, input: Input<T>): void {\n input.push(this.iso.from(change));\n }\n\n build(): { stream: Input<T>; input: Input<T> } {\n const stream = inputValue(this.graph, this.initialValue);\n return { stream, input: stream };\n }\n}\n\nexport function sink<T extends object>(graph: Graph, iso: Iso<T, object>): (snapshot: object) => Sink<Input<T>, Input<T>> {\n return (snapshot: object) => {\n return new StreamSinkAdapter<T>(graph, iso, snapshot);\n };\n}\n"],"mappings":"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","names":["sink","sink","sink"]}
|
package/dist/index.js
CHANGED
|
@@ -208,8 +208,7 @@ var Client = class {
|
|
|
208
208
|
// src/reactive-adapter.ts
|
|
209
209
|
import {
|
|
210
210
|
Reactive,
|
|
211
|
-
ChangeInput
|
|
212
|
-
asBase
|
|
211
|
+
ChangeInput
|
|
213
212
|
} from "@derivation/composable";
|
|
214
213
|
var ReactiveSourceAdapter = class {
|
|
215
214
|
constructor(stream, snapshotIso, changeIso) {
|
|
@@ -222,7 +221,7 @@ var ReactiveSourceAdapter = class {
|
|
|
222
221
|
}
|
|
223
222
|
get LastChange() {
|
|
224
223
|
const change = this.stream.changes.value;
|
|
225
|
-
if (
|
|
224
|
+
if (change === null) return null;
|
|
226
225
|
return this.changeIso.to(change);
|
|
227
226
|
}
|
|
228
227
|
get Stream() {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client-message.ts","../src/client.ts","../src/reactive-adapter.ts","../src/stream-adapter.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport const SubscribeMessageSchema = z.object({\n type: z.literal(\"subscribe\"),\n id: z.number(),\n name: z.string(),\n args: z.looseObject({}),\n});\nexport type SubscribeMessage = z.infer<typeof SubscribeMessageSchema>;\n\nexport const UnsubscribeMessageSchema = z.object({\n type: z.literal(\"unsubscribe\"),\n id: z.number(),\n});\nexport type UnsubscribeMessage = z.infer<typeof UnsubscribeMessageSchema>;\n\nexport const HeartbeatMessageSchema = z.object({\n type: z.literal(\"heartbeat\"),\n});\nexport type HeartbeatMessage = z.infer<typeof HeartbeatMessageSchema>;\n\nexport const CallMessageSchema = z.object({\n type: z.literal(\"call\"),\n id: z.number(),\n name: z.string(),\n args: z.looseObject({}),\n});\nexport type CallMessage = z.infer<typeof CallMessageSchema>;\n\nexport const PresenceMessageSchema = z.object({\n type: z.literal(\"presence\"),\n data: z.looseObject({}),\n});\nexport type PresenceMessage = z.infer<typeof PresenceMessageSchema>;\n\nexport const ClientMessageSchema = z.discriminatedUnion(\"type\", [\n SubscribeMessageSchema,\n UnsubscribeMessageSchema,\n HeartbeatMessageSchema,\n CallMessageSchema,\n PresenceMessageSchema,\n]);\nexport type ClientMessage = z.infer<typeof ClientMessageSchema>;\n\nexport function parseClientMessage(data: unknown): ClientMessage {\n return ClientMessageSchema.parse(data);\n}\n\nexport const ClientMessage = {\n subscribe: (\n id: number,\n name: string,\n args: object,\n ): SubscribeMessage => ({\n type: \"subscribe\",\n id,\n name,\n args: args as Record<string, unknown>,\n }),\n unsubscribe: (id: number): UnsubscribeMessage => ({\n type: \"unsubscribe\",\n id,\n }),\n call: (\n id: number,\n name: string,\n args: object,\n ): CallMessage => ({\n type: \"call\",\n id,\n name,\n args: args as Record<string, unknown>,\n }),\n heartbeat: (): HeartbeatMessage => ({\n type: \"heartbeat\",\n }),\n presence: (data: object): PresenceMessage => ({\n type: \"presence\",\n data: data as Record<string, unknown>,\n }),\n};\n","import { ClientMessage } from \"./client-message.js\";\nimport { ServerMessage } from \"./server-message.js\";\nimport type { Graph } from \"derivation\";\nimport type {\n Sink,\n StreamSinks,\n RPCDefinition,\n MutationResult,\n} from \"./stream-types.js\";\nimport { Transport } from \"./transport.js\";\n\nfunction changer<T extends object, I extends object>(\n sink: Sink<T, I>,\n input: WeakRef<I>,\n): (change: object) => void {\n return (change) => {\n const i = input.deref();\n if (i) {\n sink.apply(change, i);\n }\n };\n}\n\nexport class Client<Defs extends RPCDefinition> {\n private nextId = 1;\n private pendingStreams = new Map<number, (snapshot: object) => void>();\n private pendingMutations = new Map<\n number,\n (result: MutationResult<unknown>) => void\n >();\n private activeStreams = new Map<number, (change: object) => void>();\n private heartbeatTimeout: NodeJS.Timeout | undefined;\n private inactivityTimeout: NodeJS.Timeout | undefined;\n\n private registry = new FinalizationRegistry<[number, string]>(\n ([id, name]) => {\n console.log(`๐งน Stream ${id} (${name}) collected โ unsubscribing`);\n this.sendMessage(ClientMessage.unsubscribe(id));\n this.activeStreams.delete(id);\n },\n );\n\n private resetHeartbeat() {\n if (this.heartbeatTimeout) {\n clearTimeout(this.heartbeatTimeout);\n }\n\n this.heartbeatTimeout = setTimeout(() => {\n this.sendMessage(ClientMessage.heartbeat());\n }, 10_000);\n }\n\n private resetInactivity() {\n if (this.inactivityTimeout) {\n clearTimeout(this.inactivityTimeout);\n }\n\n this.inactivityTimeout = setTimeout(() => {\n this.close();\n }, 30_000);\n }\n\n constructor(\n private transport: Transport,\n private sinks: StreamSinks<Defs[\"streams\"]>,\n private graph: Graph,\n ) {\n this.transport.onMessage((data: string) => {\n const message = JSON.parse(data) as ServerMessage;\n this.handleMessage(message);\n });\n this.resetHeartbeat();\n this.resetInactivity();\n }\n\n private handleMessage(message: ServerMessage) {\n this.resetInactivity();\n\n switch (message.type) {\n case \"snapshot\": {\n console.log(`[Client] Received snapshot for stream ${message.id}`);\n const resolve = this.pendingStreams.get(message.id);\n if (resolve) {\n resolve(message.snapshot as object);\n this.pendingStreams.delete(message.id);\n }\n break;\n }\n case \"delta\": {\n const changeCount = Object.keys(message.changes).length;\n console.log(`[Client] Received delta with ${changeCount} changes for streams: ${Object.keys(message.changes).join(\", \")}`);\n for (const [idStr, change] of Object.entries(message.changes)) {\n const id = Number(idStr);\n const sink = this.activeStreams.get(id);\n\n if (sink && change && typeof change === \"object\") {\n sink(change);\n } else if (!sink) {\n console.log(`๐งน Sink ${id} GC'd โ auto-unsubscribing`);\n this.sendMessage(ClientMessage.unsubscribe(id));\n this.activeStreams.delete(id);\n }\n }\n console.log(\"[Client] Stepping graph\");\n this.graph.step();\n break;\n }\n case \"result\": {\n console.log(`[Client] Received mutation result for call ${message.id}:`, message.success ? \"success\" : \"error\");\n const resolve = this.pendingMutations.get(message.id);\n if (resolve) {\n if (message.success) {\n resolve({ success: true, value: message.value });\n } else {\n resolve({\n success: false,\n error: message.error || \"Unknown error\",\n });\n }\n this.pendingMutations.delete(message.id);\n }\n break;\n }\n case \"heartbeat\":\n console.log(\"[Client] Received heartbeat\");\n break;\n }\n }\n\n private sendMessage(message: ClientMessage) {\n this.resetHeartbeat();\n this.transport.send(JSON.stringify(message));\n }\n\n async run<Key extends keyof Defs[\"streams\"]>(\n key: Key,\n args: Defs[\"streams\"][Key][\"args\"],\n ): Promise<Defs[\"streams\"][Key][\"returnType\"]> {\n console.log(\n `Running stream ${String(key)} with args ${JSON.stringify(args)}`,\n );\n const id = this.nextId++;\n\n this.sendMessage(ClientMessage.subscribe(id, String(key), args));\n\n const snapshot = await new Promise<object>((resolve) => {\n this.pendingStreams.set(id, resolve);\n });\n\n const endpoint = this.sinks[key];\n const sinkAdapter = endpoint(snapshot);\n const { stream, input } = sinkAdapter.build();\n const inputRef = new WeakRef(input);\n this.activeStreams.set(id, changer(sinkAdapter, inputRef));\n this.registry.register(input, [id, String(key)]);\n\n return stream;\n }\n\n async call<Key extends keyof Defs[\"mutations\"]>(\n key: Key,\n args: Defs[\"mutations\"][Key][\"args\"],\n ): Promise<MutationResult<Defs[\"mutations\"][Key][\"result\"]>> {\n console.log(\n `Calling mutation ${String(key)} with args ${JSON.stringify(args)}`,\n );\n const id = this.nextId++;\n\n this.sendMessage(\n ClientMessage.call(id, String(key), args as Record<string, unknown>),\n );\n\n const result = await new Promise<\n MutationResult<Defs[\"mutations\"][Key][\"result\"]>\n >((resolve) => {\n this.pendingMutations.set(\n id,\n resolve as (result: MutationResult<unknown>) => void,\n );\n });\n\n return result;\n }\n\n close() {\n clearTimeout(this.heartbeatTimeout);\n clearTimeout(this.inactivityTimeout);\n try {\n this.transport.close();\n } catch {}\n }\n\n setPresence(value: Record<string, unknown>): void {\n this.sendMessage(ClientMessage.presence(value));\n }\n}\n","import { Graph } from \"derivation\";\nimport {\n Reactive,\n ChangeInput,\n Changes,\n OperationsBase,\n Operations,\n asBase,\n} from \"@derivation/composable\";\nimport { Source, Sink } from \"./stream-types.js\";\nimport { Iso } from \"./iso.js\";\n\nexport class ReactiveSourceAdapter<T> implements Source<Reactive<T>> {\n constructor(\n private readonly stream: Reactive<T>,\n private readonly snapshotIso: Iso<T, object>,\n private readonly changeIso: Iso<Changes<T>, object>,\n ) {}\n\n get Snapshot(): object {\n return this.snapshotIso.to(this.stream.snapshot);\n }\n\n get LastChange(): object | null {\n const change = this.stream.changes.value;\n if (asBase(this.stream.operations).isEmpty(change)) return null;\n return this.changeIso.to(change);\n }\n\n get Stream(): Reactive<T> {\n return this.stream;\n }\n}\n\nexport class ReactiveSinkAdapter<T>\n implements Sink<Reactive<T>, ChangeInput<T>>\n{\n private readonly initialValue: T;\n\n constructor(\n private readonly graph: Graph,\n snapshotIso: Iso<T, object>,\n private readonly changeIso: Iso<Changes<T>, object>,\n private readonly ops: Operations<T>,\n snapshot: object,\n ) {\n this.initialValue = snapshotIso.from(snapshot);\n }\n\n apply(change: object, input: ChangeInput<T>): void {\n input.push(this.changeIso.from(change));\n }\n\n build(): { stream: Reactive<T>; input: ChangeInput<T> } {\n const ops = this.ops;\n const input = new ChangeInput<T>(this.graph, ops);\n const stream = Reactive.create(this.graph, ops, input, this.initialValue);\n return { stream, input };\n }\n}\n\nexport function sink<T>(\n graph: Graph,\n snapshotIso: Iso<T, object>,\n changeIso: Iso<Changes<T>, object>,\n ops: Operations<T>,\n): (snapshot: object) => Sink<Reactive<T>, ChangeInput<T>> {\n return (snapshot: object) => {\n return new ReactiveSinkAdapter<T>(\n graph,\n snapshotIso,\n changeIso,\n ops,\n snapshot,\n );\n };\n}\n","import { Graph, ReactiveValue, Input, inputValue } from \"derivation\";\nimport { Source, Sink } from \"./stream-types.js\";\nimport { Iso } from \"./iso.js\";\n\nexport class StreamSourceAdapter<T extends object> implements Source<ReactiveValue<T>> {\n private readonly iso: Iso<T, object>;\n\n constructor(private readonly stream: ReactiveValue<T>, iso: Iso<T, object>) {\n this.iso = iso;\n }\n\n get Snapshot(): object {\n return this.iso.to(this.stream.value);\n }\n\n get LastChange(): object | null {\n return this.iso.to(this.stream.value);\n }\n\n get Stream(): ReactiveValue<T> {\n return this.stream;\n }\n}\n\nexport class StreamSinkAdapter<T extends object> implements Sink<Input<T>, Input<T>> {\n private readonly graph: Graph;\n private readonly iso: Iso<T, object>;\n private readonly initialValue: T;\n\n constructor(graph: Graph, iso: Iso<T, object>, snapshot: object) {\n this.graph = graph;\n this.iso = iso;\n this.initialValue = iso.from(snapshot);\n }\n\n apply(change: object, input: Input<T>): void {\n input.push(this.iso.from(change));\n }\n\n build(): { stream: Input<T>; input: Input<T> } {\n const stream = inputValue(this.graph, this.initialValue);\n return { stream, input: stream };\n }\n}\n\nexport function sink<T extends object>(graph: Graph, iso: Iso<T, object>): (snapshot: object) => Sink<Input<T>, Input<T>> {\n return (snapshot: object) => {\n return new StreamSinkAdapter<T>(graph, iso, snapshot);\n };\n}\n"],"mappings":";AAAA,SAAS,SAAS;AAEX,IAAM,yBAAyB,EAAE,OAAO;AAAA,EAC7C,MAAM,EAAE,QAAQ,WAAW;AAAA,EAC3B,IAAI,EAAE,OAAO;AAAA,EACb,MAAM,EAAE,OAAO;AAAA,EACf,MAAM,EAAE,YAAY,CAAC,CAAC;AACxB,CAAC;AAGM,IAAM,2BAA2B,EAAE,OAAO;AAAA,EAC/C,MAAM,EAAE,QAAQ,aAAa;AAAA,EAC7B,IAAI,EAAE,OAAO;AACf,CAAC;AAGM,IAAM,yBAAyB,EAAE,OAAO;AAAA,EAC7C,MAAM,EAAE,QAAQ,WAAW;AAC7B,CAAC;AAGM,IAAM,oBAAoB,EAAE,OAAO;AAAA,EACxC,MAAM,EAAE,QAAQ,MAAM;AAAA,EACtB,IAAI,EAAE,OAAO;AAAA,EACb,MAAM,EAAE,OAAO;AAAA,EACf,MAAM,EAAE,YAAY,CAAC,CAAC;AACxB,CAAC;AAGM,IAAM,wBAAwB,EAAE,OAAO;AAAA,EAC5C,MAAM,EAAE,QAAQ,UAAU;AAAA,EAC1B,MAAM,EAAE,YAAY,CAAC,CAAC;AACxB,CAAC;AAGM,IAAM,sBAAsB,EAAE,mBAAmB,QAAQ;AAAA,EAC9D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAOM,IAAM,gBAAgB;AAAA,EAC3B,WAAW,CACT,IACA,MACA,UACsB;AAAA,IACtB,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,aAAa,CAAC,QAAoC;AAAA,IAChD,MAAM;AAAA,IACN;AAAA,EACF;AAAA,EACA,MAAM,CACJ,IACA,MACA,UACiB;AAAA,IACjB,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,WAAW,OAAyB;AAAA,IAClC,MAAM;AAAA,EACR;AAAA,EACA,UAAU,CAAC,UAAmC;AAAA,IAC5C,MAAM;AAAA,IACN;AAAA,EACF;AACF;;;ACrEA,SAAS,QACPA,OACA,OAC0B;AAC1B,SAAO,CAAC,WAAW;AACjB,UAAM,IAAI,MAAM,MAAM;AACtB,QAAI,GAAG;AACL,MAAAA,MAAK,MAAM,QAAQ,CAAC;AAAA,IACtB;AAAA,EACF;AACF;AAEO,IAAM,SAAN,MAAyC;AAAA,EAuC9C,YACU,WACA,OACA,OACR;AAHQ;AACA;AACA;AAzCV,SAAQ,SAAS;AACjB,SAAQ,iBAAiB,oBAAI,IAAwC;AACrE,SAAQ,mBAAmB,oBAAI,IAG7B;AACF,SAAQ,gBAAgB,oBAAI,IAAsC;AAIlE,SAAQ,WAAW,IAAI;AAAA,MACrB,CAAC,CAAC,IAAI,IAAI,MAAM;AACd,gBAAQ,IAAI,oBAAa,EAAE,KAAK,IAAI,kCAA6B;AACjE,aAAK,YAAY,cAAc,YAAY,EAAE,CAAC;AAC9C,aAAK,cAAc,OAAO,EAAE;AAAA,MAC9B;AAAA,IACF;AA2BE,SAAK,UAAU,UAAU,CAAC,SAAiB;AACzC,YAAM,UAAU,KAAK,MAAM,IAAI;AAC/B,WAAK,cAAc,OAAO;AAAA,IAC5B,CAAC;AACD,SAAK,eAAe;AACpB,SAAK,gBAAgB;AAAA,EACvB;AAAA,EA/BQ,iBAAiB;AACvB,QAAI,KAAK,kBAAkB;AACzB,mBAAa,KAAK,gBAAgB;AAAA,IACpC;AAEA,SAAK,mBAAmB,WAAW,MAAM;AACvC,WAAK,YAAY,cAAc,UAAU,CAAC;AAAA,IAC5C,GAAG,GAAM;AAAA,EACX;AAAA,EAEQ,kBAAkB;AACxB,QAAI,KAAK,mBAAmB;AAC1B,mBAAa,KAAK,iBAAiB;AAAA,IACrC;AAEA,SAAK,oBAAoB,WAAW,MAAM;AACxC,WAAK,MAAM;AAAA,IACb,GAAG,GAAM;AAAA,EACX;AAAA,EAeQ,cAAc,SAAwB;AAC5C,SAAK,gBAAgB;AAErB,YAAQ,QAAQ,MAAM;AAAA,MACpB,KAAK,YAAY;AACf,gBAAQ,IAAI,yCAAyC,QAAQ,EAAE,EAAE;AACjE,cAAM,UAAU,KAAK,eAAe,IAAI,QAAQ,EAAE;AAClD,YAAI,SAAS;AACX,kBAAQ,QAAQ,QAAkB;AAClC,eAAK,eAAe,OAAO,QAAQ,EAAE;AAAA,QACvC;AACA;AAAA,MACF;AAAA,MACA,KAAK,SAAS;AACZ,cAAM,cAAc,OAAO,KAAK,QAAQ,OAAO,EAAE;AACjD,gBAAQ,IAAI,gCAAgC,WAAW,yBAAyB,OAAO,KAAK,QAAQ,OAAO,EAAE,KAAK,IAAI,CAAC,EAAE;AACzH,mBAAW,CAAC,OAAO,MAAM,KAAK,OAAO,QAAQ,QAAQ,OAAO,GAAG;AAC7D,gBAAM,KAAK,OAAO,KAAK;AACvB,gBAAMA,QAAO,KAAK,cAAc,IAAI,EAAE;AAEtC,cAAIA,SAAQ,UAAU,OAAO,WAAW,UAAU;AAChD,YAAAA,MAAK,MAAM;AAAA,UACb,WAAW,CAACA,OAAM;AAChB,oBAAQ,IAAI,kBAAW,EAAE,iCAA4B;AACrD,iBAAK,YAAY,cAAc,YAAY,EAAE,CAAC;AAC9C,iBAAK,cAAc,OAAO,EAAE;AAAA,UAC9B;AAAA,QACF;AACA,gBAAQ,IAAI,yBAAyB;AACrC,aAAK,MAAM,KAAK;AAChB;AAAA,MACF;AAAA,MACA,KAAK,UAAU;AACb,gBAAQ,IAAI,8CAA8C,QAAQ,EAAE,KAAK,QAAQ,UAAU,YAAY,OAAO;AAC9G,cAAM,UAAU,KAAK,iBAAiB,IAAI,QAAQ,EAAE;AACpD,YAAI,SAAS;AACX,cAAI,QAAQ,SAAS;AACnB,oBAAQ,EAAE,SAAS,MAAM,OAAO,QAAQ,MAAM,CAAC;AAAA,UACjD,OAAO;AACL,oBAAQ;AAAA,cACN,SAAS;AAAA,cACT,OAAO,QAAQ,SAAS;AAAA,YAC1B,CAAC;AAAA,UACH;AACA,eAAK,iBAAiB,OAAO,QAAQ,EAAE;AAAA,QACzC;AACA;AAAA,MACF;AAAA,MACA,KAAK;AACH,gBAAQ,IAAI,6BAA6B;AACzC;AAAA,IACJ;AAAA,EACF;AAAA,EAEQ,YAAY,SAAwB;AAC1C,SAAK,eAAe;AACpB,SAAK,UAAU,KAAK,KAAK,UAAU,OAAO,CAAC;AAAA,EAC7C;AAAA,EAEA,MAAM,IACJ,KACA,MAC6C;AAC7C,YAAQ;AAAA,MACN,kBAAkB,OAAO,GAAG,CAAC,cAAc,KAAK,UAAU,IAAI,CAAC;AAAA,IACjE;AACA,UAAM,KAAK,KAAK;AAEhB,SAAK,YAAY,cAAc,UAAU,IAAI,OAAO,GAAG,GAAG,IAAI,CAAC;AAE/D,UAAM,WAAW,MAAM,IAAI,QAAgB,CAAC,YAAY;AACtD,WAAK,eAAe,IAAI,IAAI,OAAO;AAAA,IACrC,CAAC;AAED,UAAM,WAAW,KAAK,MAAM,GAAG;AAC/B,UAAM,cAAc,SAAS,QAAQ;AACrC,UAAM,EAAE,QAAQ,MAAM,IAAI,YAAY,MAAM;AAC5C,UAAM,WAAW,IAAI,QAAQ,KAAK;AAClC,SAAK,cAAc,IAAI,IAAI,QAAQ,aAAa,QAAQ,CAAC;AACzD,SAAK,SAAS,SAAS,OAAO,CAAC,IAAI,OAAO,GAAG,CAAC,CAAC;AAE/C,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,KACJ,KACA,MAC2D;AAC3D,YAAQ;AAAA,MACN,oBAAoB,OAAO,GAAG,CAAC,cAAc,KAAK,UAAU,IAAI,CAAC;AAAA,IACnE;AACA,UAAM,KAAK,KAAK;AAEhB,SAAK;AAAA,MACH,cAAc,KAAK,IAAI,OAAO,GAAG,GAAG,IAA+B;AAAA,IACrE;AAEA,UAAM,SAAS,MAAM,IAAI,QAEvB,CAAC,YAAY;AACb,WAAK,iBAAiB;AAAA,QACpB;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AAED,WAAO;AAAA,EACT;AAAA,EAEA,QAAQ;AACN,iBAAa,KAAK,gBAAgB;AAClC,iBAAa,KAAK,iBAAiB;AACnC,QAAI;AACF,WAAK,UAAU,MAAM;AAAA,IACvB,SAAQ;AAAA,IAAC;AAAA,EACX;AAAA,EAEA,YAAY,OAAsC;AAChD,SAAK,YAAY,cAAc,SAAS,KAAK,CAAC;AAAA,EAChD;AACF;;;AClMA;AAAA,EACE;AAAA,EACA;AAAA,EAIA;AAAA,OACK;AAIA,IAAM,wBAAN,MAA8D;AAAA,EACnE,YACmB,QACA,aACA,WACjB;AAHiB;AACA;AACA;AAAA,EAChB;AAAA,EAEH,IAAI,WAAmB;AACrB,WAAO,KAAK,YAAY,GAAG,KAAK,OAAO,QAAQ;AAAA,EACjD;AAAA,EAEA,IAAI,aAA4B;AAC9B,UAAM,SAAS,KAAK,OAAO,QAAQ;AACnC,QAAI,OAAO,KAAK,OAAO,UAAU,EAAE,QAAQ,MAAM,EAAG,QAAO;AAC3D,WAAO,KAAK,UAAU,GAAG,MAAM;AAAA,EACjC;AAAA,EAEA,IAAI,SAAsB;AACxB,WAAO,KAAK;AAAA,EACd;AACF;AAEO,IAAM,sBAAN,MAEP;AAAA,EAGE,YACmB,OACjB,aACiB,WACA,KACjB,UACA;AALiB;AAEA;AACA;AAGjB,SAAK,eAAe,YAAY,KAAK,QAAQ;AAAA,EAC/C;AAAA,EAEA,MAAM,QAAgB,OAA6B;AACjD,UAAM,KAAK,KAAK,UAAU,KAAK,MAAM,CAAC;AAAA,EACxC;AAAA,EAEA,QAAwD;AACtD,UAAM,MAAM,KAAK;AACjB,UAAM,QAAQ,IAAI,YAAe,KAAK,OAAO,GAAG;AAChD,UAAM,SAAS,SAAS,OAAO,KAAK,OAAO,KAAK,OAAO,KAAK,YAAY;AACxE,WAAO,EAAE,QAAQ,MAAM;AAAA,EACzB;AACF;AAEO,SAAS,KACd,OACA,aACA,WACA,KACyD;AACzD,SAAO,CAAC,aAAqB;AAC3B,WAAO,IAAI;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;;;AC5EA,SAAsC,kBAAkB;AAIjD,IAAM,sBAAN,MAAgF;AAAA,EAGrF,YAA6B,QAA0B,KAAqB;AAA/C;AAC3B,SAAK,MAAM;AAAA,EACb;AAAA,EAEA,IAAI,WAAmB;AACrB,WAAO,KAAK,IAAI,GAAG,KAAK,OAAO,KAAK;AAAA,EACtC;AAAA,EAEA,IAAI,aAA4B;AAC9B,WAAO,KAAK,IAAI,GAAG,KAAK,OAAO,KAAK;AAAA,EACtC;AAAA,EAEA,IAAI,SAA2B;AAC7B,WAAO,KAAK;AAAA,EACd;AACF;AAEO,IAAM,oBAAN,MAA8E;AAAA,EAKnF,YAAY,OAAc,KAAqB,UAAkB;AAC/D,SAAK,QAAQ;AACb,SAAK,MAAM;AACX,SAAK,eAAe,IAAI,KAAK,QAAQ;AAAA,EACvC;AAAA,EAEA,MAAM,QAAgB,OAAuB;AAC3C,UAAM,KAAK,KAAK,IAAI,KAAK,MAAM,CAAC;AAAA,EAClC;AAAA,EAEA,QAA+C;AAC7C,UAAM,SAAS,WAAW,KAAK,OAAO,KAAK,YAAY;AACvD,WAAO,EAAE,QAAQ,OAAO,OAAO;AAAA,EACjC;AACF;AAEO,SAASC,MAAuB,OAAc,KAAqE;AACxH,SAAO,CAAC,aAAqB;AAC3B,WAAO,IAAI,kBAAqB,OAAO,KAAK,QAAQ;AAAA,EACtD;AACF;","names":["sink","sink"]}
|
|
1
|
+
{"version":3,"sources":["../src/client-message.ts","../src/client.ts","../src/reactive-adapter.ts","../src/stream-adapter.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport const SubscribeMessageSchema = z.object({\n type: z.literal(\"subscribe\"),\n id: z.number(),\n name: z.string(),\n args: z.looseObject({}),\n});\nexport type SubscribeMessage = z.infer<typeof SubscribeMessageSchema>;\n\nexport const UnsubscribeMessageSchema = z.object({\n type: z.literal(\"unsubscribe\"),\n id: z.number(),\n});\nexport type UnsubscribeMessage = z.infer<typeof UnsubscribeMessageSchema>;\n\nexport const HeartbeatMessageSchema = z.object({\n type: z.literal(\"heartbeat\"),\n});\nexport type HeartbeatMessage = z.infer<typeof HeartbeatMessageSchema>;\n\nexport const CallMessageSchema = z.object({\n type: z.literal(\"call\"),\n id: z.number(),\n name: z.string(),\n args: z.looseObject({}),\n});\nexport type CallMessage = z.infer<typeof CallMessageSchema>;\n\nexport const PresenceMessageSchema = z.object({\n type: z.literal(\"presence\"),\n data: z.looseObject({}),\n});\nexport type PresenceMessage = z.infer<typeof PresenceMessageSchema>;\n\nexport const ClientMessageSchema = z.discriminatedUnion(\"type\", [\n SubscribeMessageSchema,\n UnsubscribeMessageSchema,\n HeartbeatMessageSchema,\n CallMessageSchema,\n PresenceMessageSchema,\n]);\nexport type ClientMessage = z.infer<typeof ClientMessageSchema>;\n\nexport function parseClientMessage(data: unknown): ClientMessage {\n return ClientMessageSchema.parse(data);\n}\n\nexport const ClientMessage = {\n subscribe: (\n id: number,\n name: string,\n args: object,\n ): SubscribeMessage => ({\n type: \"subscribe\",\n id,\n name,\n args: args as Record<string, unknown>,\n }),\n unsubscribe: (id: number): UnsubscribeMessage => ({\n type: \"unsubscribe\",\n id,\n }),\n call: (\n id: number,\n name: string,\n args: object,\n ): CallMessage => ({\n type: \"call\",\n id,\n name,\n args: args as Record<string, unknown>,\n }),\n heartbeat: (): HeartbeatMessage => ({\n type: \"heartbeat\",\n }),\n presence: (data: object): PresenceMessage => ({\n type: \"presence\",\n data: data as Record<string, unknown>,\n }),\n};\n","import { ClientMessage } from \"./client-message.js\";\nimport { ServerMessage } from \"./server-message.js\";\nimport type { Graph } from \"derivation\";\nimport type {\n Sink,\n StreamSinks,\n RPCDefinition,\n MutationResult,\n} from \"./stream-types.js\";\nimport { Transport } from \"./transport.js\";\n\nfunction changer<T extends object, I extends object>(\n sink: Sink<T, I>,\n input: WeakRef<I>,\n): (change: object) => void {\n return (change) => {\n const i = input.deref();\n if (i) {\n sink.apply(change, i);\n }\n };\n}\n\nexport class Client<Defs extends RPCDefinition> {\n private nextId = 1;\n private pendingStreams = new Map<number, (snapshot: object) => void>();\n private pendingMutations = new Map<\n number,\n (result: MutationResult<unknown>) => void\n >();\n private activeStreams = new Map<number, (change: object) => void>();\n private heartbeatTimeout: NodeJS.Timeout | undefined;\n private inactivityTimeout: NodeJS.Timeout | undefined;\n\n private registry = new FinalizationRegistry<[number, string]>(\n ([id, name]) => {\n console.log(`๐งน Stream ${id} (${name}) collected โ unsubscribing`);\n this.sendMessage(ClientMessage.unsubscribe(id));\n this.activeStreams.delete(id);\n },\n );\n\n private resetHeartbeat() {\n if (this.heartbeatTimeout) {\n clearTimeout(this.heartbeatTimeout);\n }\n\n this.heartbeatTimeout = setTimeout(() => {\n this.sendMessage(ClientMessage.heartbeat());\n }, 10_000);\n }\n\n private resetInactivity() {\n if (this.inactivityTimeout) {\n clearTimeout(this.inactivityTimeout);\n }\n\n this.inactivityTimeout = setTimeout(() => {\n this.close();\n }, 30_000);\n }\n\n constructor(\n private transport: Transport,\n private sinks: StreamSinks<Defs[\"streams\"]>,\n private graph: Graph,\n ) {\n this.transport.onMessage((data: string) => {\n const message = JSON.parse(data) as ServerMessage;\n this.handleMessage(message);\n });\n this.resetHeartbeat();\n this.resetInactivity();\n }\n\n private handleMessage(message: ServerMessage) {\n this.resetInactivity();\n\n switch (message.type) {\n case \"snapshot\": {\n console.log(`[Client] Received snapshot for stream ${message.id}`);\n const resolve = this.pendingStreams.get(message.id);\n if (resolve) {\n resolve(message.snapshot as object);\n this.pendingStreams.delete(message.id);\n }\n break;\n }\n case \"delta\": {\n const changeCount = Object.keys(message.changes).length;\n console.log(`[Client] Received delta with ${changeCount} changes for streams: ${Object.keys(message.changes).join(\", \")}`);\n for (const [idStr, change] of Object.entries(message.changes)) {\n const id = Number(idStr);\n const sink = this.activeStreams.get(id);\n\n if (sink && change && typeof change === \"object\") {\n sink(change);\n } else if (!sink) {\n console.log(`๐งน Sink ${id} GC'd โ auto-unsubscribing`);\n this.sendMessage(ClientMessage.unsubscribe(id));\n this.activeStreams.delete(id);\n }\n }\n console.log(\"[Client] Stepping graph\");\n this.graph.step();\n break;\n }\n case \"result\": {\n console.log(`[Client] Received mutation result for call ${message.id}:`, message.success ? \"success\" : \"error\");\n const resolve = this.pendingMutations.get(message.id);\n if (resolve) {\n if (message.success) {\n resolve({ success: true, value: message.value });\n } else {\n resolve({\n success: false,\n error: message.error || \"Unknown error\",\n });\n }\n this.pendingMutations.delete(message.id);\n }\n break;\n }\n case \"heartbeat\":\n console.log(\"[Client] Received heartbeat\");\n break;\n }\n }\n\n private sendMessage(message: ClientMessage) {\n this.resetHeartbeat();\n this.transport.send(JSON.stringify(message));\n }\n\n async run<Key extends keyof Defs[\"streams\"]>(\n key: Key,\n args: Defs[\"streams\"][Key][\"args\"],\n ): Promise<Defs[\"streams\"][Key][\"returnType\"]> {\n console.log(\n `Running stream ${String(key)} with args ${JSON.stringify(args)}`,\n );\n const id = this.nextId++;\n\n this.sendMessage(ClientMessage.subscribe(id, String(key), args));\n\n const snapshot = await new Promise<object>((resolve) => {\n this.pendingStreams.set(id, resolve);\n });\n\n const endpoint = this.sinks[key];\n const sinkAdapter = endpoint(snapshot);\n const { stream, input } = sinkAdapter.build();\n const inputRef = new WeakRef(input);\n this.activeStreams.set(id, changer(sinkAdapter, inputRef));\n this.registry.register(input, [id, String(key)]);\n\n return stream;\n }\n\n async call<Key extends keyof Defs[\"mutations\"]>(\n key: Key,\n args: Defs[\"mutations\"][Key][\"args\"],\n ): Promise<MutationResult<Defs[\"mutations\"][Key][\"result\"]>> {\n console.log(\n `Calling mutation ${String(key)} with args ${JSON.stringify(args)}`,\n );\n const id = this.nextId++;\n\n this.sendMessage(\n ClientMessage.call(id, String(key), args as Record<string, unknown>),\n );\n\n const result = await new Promise<\n MutationResult<Defs[\"mutations\"][Key][\"result\"]>\n >((resolve) => {\n this.pendingMutations.set(\n id,\n resolve as (result: MutationResult<unknown>) => void,\n );\n });\n\n return result;\n }\n\n close() {\n clearTimeout(this.heartbeatTimeout);\n clearTimeout(this.inactivityTimeout);\n try {\n this.transport.close();\n } catch {}\n }\n\n setPresence(value: Record<string, unknown>): void {\n this.sendMessage(ClientMessage.presence(value));\n }\n}\n","import { Graph } from \"derivation\";\nimport {\n Reactive,\n ChangeInput,\n Changes,\n OperationsBase,\n Operations,\n asBase,\n} from \"@derivation/composable\";\nimport { Source, Sink } from \"./stream-types.js\";\nimport { Iso } from \"./iso.js\";\n\nexport class ReactiveSourceAdapter<T> implements Source<Reactive<T>> {\n constructor(\n private readonly stream: Reactive<T>,\n private readonly snapshotIso: Iso<T, object>,\n private readonly changeIso: Iso<Changes<T>, object>,\n ) {}\n\n get Snapshot(): object {\n return this.snapshotIso.to(this.stream.snapshot);\n }\n\n get LastChange(): object | null {\n const change = this.stream.changes.value;\n if (change === null) return null;\n return this.changeIso.to(change);\n }\n\n get Stream(): Reactive<T> {\n return this.stream;\n }\n}\n\nexport class ReactiveSinkAdapter<T>\n implements Sink<Reactive<T>, ChangeInput<T>>\n{\n private readonly initialValue: T;\n\n constructor(\n private readonly graph: Graph,\n snapshotIso: Iso<T, object>,\n private readonly changeIso: Iso<Changes<T>, object>,\n private readonly ops: Operations<T>,\n snapshot: object,\n ) {\n this.initialValue = snapshotIso.from(snapshot);\n }\n\n apply(change: object, input: ChangeInput<T>): void {\n input.push(this.changeIso.from(change));\n }\n\n build(): { stream: Reactive<T>; input: ChangeInput<T> } {\n const ops = this.ops;\n const input = new ChangeInput<T>(this.graph, ops);\n const stream = Reactive.create(this.graph, ops, input, this.initialValue);\n return { stream, input };\n }\n}\n\nexport function sink<T>(\n graph: Graph,\n snapshotIso: Iso<T, object>,\n changeIso: Iso<Changes<T>, object>,\n ops: Operations<T>,\n): (snapshot: object) => Sink<Reactive<T>, ChangeInput<T>> {\n return (snapshot: object) => {\n return new ReactiveSinkAdapter<T>(\n graph,\n snapshotIso,\n changeIso,\n ops,\n snapshot,\n );\n };\n}\n","import { Graph, ReactiveValue, Input, inputValue } from \"derivation\";\nimport { Source, Sink } from \"./stream-types.js\";\nimport { Iso } from \"./iso.js\";\n\nexport class StreamSourceAdapter<T extends object> implements Source<ReactiveValue<T>> {\n private readonly iso: Iso<T, object>;\n\n constructor(private readonly stream: ReactiveValue<T>, iso: Iso<T, object>) {\n this.iso = iso;\n }\n\n get Snapshot(): object {\n return this.iso.to(this.stream.value);\n }\n\n get LastChange(): object | null {\n return this.iso.to(this.stream.value);\n }\n\n get Stream(): ReactiveValue<T> {\n return this.stream;\n }\n}\n\nexport class StreamSinkAdapter<T extends object> implements Sink<Input<T>, Input<T>> {\n private readonly graph: Graph;\n private readonly iso: Iso<T, object>;\n private readonly initialValue: T;\n\n constructor(graph: Graph, iso: Iso<T, object>, snapshot: object) {\n this.graph = graph;\n this.iso = iso;\n this.initialValue = iso.from(snapshot);\n }\n\n apply(change: object, input: Input<T>): void {\n input.push(this.iso.from(change));\n }\n\n build(): { stream: Input<T>; input: Input<T> } {\n const stream = inputValue(this.graph, this.initialValue);\n return { stream, input: stream };\n }\n}\n\nexport function sink<T extends object>(graph: Graph, iso: Iso<T, object>): (snapshot: object) => Sink<Input<T>, Input<T>> {\n return (snapshot: object) => {\n return new StreamSinkAdapter<T>(graph, iso, snapshot);\n };\n}\n"],"mappings":"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","names":["sink","sink"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@derivation/rpc",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"homepage": "https://github.com/derivationjs/rpc",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -61,18 +61,18 @@
|
|
|
61
61
|
"lint": "eslint src"
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
|
-
"derivation": "^0.
|
|
65
|
-
"@derivation/composable": "^0.
|
|
66
|
-
"@types/node": "^25.2.
|
|
64
|
+
"derivation": "^0.5.0",
|
|
65
|
+
"@derivation/composable": "^0.5.0",
|
|
66
|
+
"@types/node": "^25.2.3",
|
|
67
67
|
"@types/ws": "^8.18.1",
|
|
68
68
|
"immutable": "^5.1.4",
|
|
69
69
|
"ws": "^8.19.0",
|
|
70
70
|
"zod": "^4.3.6"
|
|
71
71
|
},
|
|
72
72
|
"devDependencies": {
|
|
73
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
74
|
-
"@typescript-eslint/parser": "^8.
|
|
75
|
-
"eslint": "^
|
|
73
|
+
"@typescript-eslint/eslint-plugin": "^8.55.0",
|
|
74
|
+
"@typescript-eslint/parser": "^8.55.0",
|
|
75
|
+
"eslint": "^9.0.0",
|
|
76
76
|
"eslint-plugin-import": "^2.32.0",
|
|
77
77
|
"tsup": "^8.5.1",
|
|
78
78
|
"typescript": "^5.9.3",
|