@derivation/rpc 0.3.5 → 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/client-DJZfuakf.d.cts +27 -0
- package/dist/{client.d.ts → client-TPsVZH_B.d.ts} +7 -4
- package/dist/index.cjs +335 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +55 -0
- package/dist/index.d.ts +55 -7
- package/dist/index.js +305 -6
- package/dist/index.js.map +1 -0
- package/dist/iso.cjs +151 -0
- package/dist/iso.cjs.map +1 -0
- package/dist/iso.d.cts +52 -0
- package/dist/iso.d.ts +35 -19
- package/dist/iso.js +99 -101
- package/dist/iso.js.map +1 -0
- package/dist/{presence-manager.d.ts → presence-manager-4LlEyuGp.d.cts} +3 -1
- package/dist/presence-manager-4LlEyuGp.d.ts +7 -0
- package/dist/shared-worker-client.cjs +271 -0
- package/dist/shared-worker-client.cjs.map +1 -0
- package/dist/shared-worker-client.d.cts +26 -0
- package/dist/shared-worker-client.d.ts +8 -4
- package/dist/shared-worker-client.js +243 -24
- package/dist/shared-worker-client.js.map +1 -0
- package/dist/shared-worker-server.cjs +363 -0
- package/dist/shared-worker-server.cjs.map +1 -0
- package/dist/shared-worker-server.d.cts +31 -0
- package/dist/shared-worker-server.d.ts +9 -6
- package/dist/shared-worker-server.js +332 -58
- package/dist/shared-worker-server.js.map +1 -0
- package/dist/stream-types-Q_EqNLtO.d.cts +46 -0
- package/dist/stream-types-Q_EqNLtO.d.ts +46 -0
- package/dist/transport.cjs +19 -0
- package/dist/transport.cjs.map +1 -0
- package/dist/transport.d.cts +29 -0
- package/dist/transport.d.ts +3 -1
- package/dist/transport.js +1 -1
- package/dist/transport.js.map +1 -0
- package/dist/web-socket-server.cjs +469 -0
- package/dist/web-socket-server.cjs.map +1 -0
- package/dist/web-socket-server.d.cts +14 -0
- package/dist/web-socket-server.d.ts +10 -7
- package/dist/web-socket-server.js +437 -52
- package/dist/web-socket-server.js.map +1 -0
- package/dist/web-socket-transport.cjs +52 -0
- package/dist/web-socket-transport.cjs.map +1 -0
- package/dist/web-socket-transport.d.cts +16 -0
- package/dist/web-socket-transport.d.ts +5 -2
- package/dist/web-socket-transport.js +27 -25
- package/dist/web-socket-transport.js.map +1 -0
- package/package.json +26 -17
- package/dist/client-handler.d.ts +0 -27
- package/dist/client-handler.js +0 -187
- package/dist/client-message.d.ts +0 -57
- package/dist/client-message.js +0 -59
- package/dist/client.js +0 -133
- package/dist/messageport-transport.d.ts +0 -13
- package/dist/messageport-transport.js +0 -28
- package/dist/node-web-socket-transport.d.ts +0 -16
- package/dist/node-web-socket-transport.js +0 -33
- package/dist/presence-manager.js +0 -1
- package/dist/queue.d.ts +0 -9
- package/dist/queue.js +0 -32
- package/dist/rate-limiter.d.ts +0 -7
- package/dist/rate-limiter.js +0 -24
- package/dist/reactive-map-adapter.d.ts +0 -24
- package/dist/reactive-map-adapter.js +0 -43
- package/dist/reactive-set-adapter.d.ts +0 -24
- package/dist/reactive-set-adapter.js +0 -41
- package/dist/server-message.d.ts +0 -48
- package/dist/server-message.js +0 -52
- package/dist/shared-worker-client-handler.d.ts +0 -27
- package/dist/shared-worker-client-handler.js +0 -149
- package/dist/stream-adapter.d.ts +0 -23
- package/dist/stream-adapter.js +0 -35
- package/dist/stream-types.d.ts +0 -44
- package/dist/stream-types.js +0 -1
- package/dist/tests/context.test.d.ts +0 -1
- package/dist/tests/context.test.js +0 -252
- package/dist/tests/iso.test.d.ts +0 -1
- package/dist/tests/iso.test.js +0 -186
- package/dist/tests/messages.test.d.ts +0 -1
- package/dist/tests/messages.test.js +0 -152
- package/dist/tests/mutations.test.d.ts +0 -1
- package/dist/tests/mutations.test.js +0 -122
- package/dist/tests/queue.test.d.ts +0 -1
- package/dist/tests/queue.test.js +0 -84
- package/dist/tests/reactive-map-adapter.test.d.ts +0 -1
- package/dist/tests/reactive-map-adapter.test.js +0 -190
- package/dist/tests/reactive-set-adapter.test.d.ts +0 -1
- package/dist/tests/reactive-set-adapter.test.js +0 -157
- package/dist/tests/stream-adapter.test.d.ts +0 -1
- package/dist/tests/stream-adapter.test.js +0 -119
- package/dist/tests/weak-list.test.d.ts +0 -1
- package/dist/tests/weak-list.test.js +0 -100
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/dist/weak-list.d.ts +0 -5
- package/dist/weak-list.js +0 -19
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Transport implementation for Node.js WebSocket (server-side using 'ws' library).
|
|
3
|
-
*/
|
|
4
|
-
export class NodeWebSocketTransport {
|
|
5
|
-
constructor(ws) {
|
|
6
|
-
this.ws = ws;
|
|
7
|
-
this.messageHandlerSet = false;
|
|
8
|
-
this.closeHandlerSet = false;
|
|
9
|
-
}
|
|
10
|
-
send(data) {
|
|
11
|
-
this.ws.send(data);
|
|
12
|
-
}
|
|
13
|
-
onMessage(handler) {
|
|
14
|
-
if (!this.messageHandlerSet) {
|
|
15
|
-
this.ws.on("message", (data) => {
|
|
16
|
-
handler(data.toString());
|
|
17
|
-
});
|
|
18
|
-
this.messageHandlerSet = true;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
onClose(handler) {
|
|
22
|
-
if (!this.closeHandlerSet) {
|
|
23
|
-
this.ws.on("close", handler);
|
|
24
|
-
this.closeHandlerSet = true;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
close() {
|
|
28
|
-
this.ws.close();
|
|
29
|
-
}
|
|
30
|
-
get bufferedAmount() {
|
|
31
|
-
return this.ws.bufferedAmount;
|
|
32
|
-
}
|
|
33
|
-
}
|
package/dist/presence-manager.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/queue.d.ts
DELETED
package/dist/queue.js
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
export class Queue {
|
|
2
|
-
constructor() {
|
|
3
|
-
this.front = [];
|
|
4
|
-
this.back = [];
|
|
5
|
-
}
|
|
6
|
-
get length() {
|
|
7
|
-
return this.front.length + this.back.length;
|
|
8
|
-
}
|
|
9
|
-
isEmpty() {
|
|
10
|
-
return this.front.length === 0 && this.back.length === 0;
|
|
11
|
-
}
|
|
12
|
-
push(item) {
|
|
13
|
-
this.front.push(item);
|
|
14
|
-
}
|
|
15
|
-
peek() {
|
|
16
|
-
if (this.back.length === 0) {
|
|
17
|
-
if (this.front.length === 0) {
|
|
18
|
-
return undefined;
|
|
19
|
-
}
|
|
20
|
-
return this.front[0];
|
|
21
|
-
}
|
|
22
|
-
return this.back[this.back.length - 1];
|
|
23
|
-
}
|
|
24
|
-
pop() {
|
|
25
|
-
if (this.back.length === 0) {
|
|
26
|
-
// Reverse front and swap to back
|
|
27
|
-
this.back = this.front.reverse();
|
|
28
|
-
this.front = [];
|
|
29
|
-
}
|
|
30
|
-
return this.back.pop();
|
|
31
|
-
}
|
|
32
|
-
}
|
package/dist/rate-limiter.d.ts
DELETED
package/dist/rate-limiter.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { Queue } from "./queue.js";
|
|
2
|
-
export class RateLimiter {
|
|
3
|
-
constructor(maxOccurrences, windowSeconds) {
|
|
4
|
-
this.timestamps = new Queue();
|
|
5
|
-
this.maxOccurrences = maxOccurrences;
|
|
6
|
-
this.windowNanos = BigInt(windowSeconds) * BigInt(1000000000);
|
|
7
|
-
}
|
|
8
|
-
trigger() {
|
|
9
|
-
const now = process.hrtime.bigint();
|
|
10
|
-
const cutoff = now - this.windowNanos;
|
|
11
|
-
while (!this.timestamps.isEmpty()) {
|
|
12
|
-
const oldest = this.timestamps.peek();
|
|
13
|
-
if (oldest === undefined || oldest >= cutoff) {
|
|
14
|
-
break;
|
|
15
|
-
}
|
|
16
|
-
this.timestamps.pop();
|
|
17
|
-
}
|
|
18
|
-
if (this.timestamps.length >= this.maxOccurrences) {
|
|
19
|
-
return true;
|
|
20
|
-
}
|
|
21
|
-
this.timestamps.push(now);
|
|
22
|
-
return false;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { Graph } from "derivation";
|
|
2
|
-
import { ZMap, Reactive, ZMapChangeInput } from "@derivation/composable";
|
|
3
|
-
import { Source, Sink } from "./stream-types.js";
|
|
4
|
-
import { Iso } from "./iso.js";
|
|
5
|
-
export declare class ReactiveMapSourceAdapter<K, V> implements Source<Reactive<ZMap<K, V>>> {
|
|
6
|
-
private readonly map;
|
|
7
|
-
private readonly iso;
|
|
8
|
-
constructor(map: Reactive<ZMap<K, V>>, keyIso: Iso<K, unknown>, valueIso: Iso<V, unknown>);
|
|
9
|
-
get Snapshot(): object;
|
|
10
|
-
get LastChange(): object | null;
|
|
11
|
-
get Stream(): Reactive<ZMap<K, V>>;
|
|
12
|
-
}
|
|
13
|
-
export declare class ReactiveMapSinkAdapter<K, V> implements Sink<Reactive<ZMap<K, V>>, ZMapChangeInput<K, V>> {
|
|
14
|
-
private readonly graph;
|
|
15
|
-
private readonly iso;
|
|
16
|
-
private readonly initialMap;
|
|
17
|
-
constructor(graph: Graph, keyIso: Iso<K, unknown>, valueIso: Iso<V, unknown>, snapshot: object);
|
|
18
|
-
apply(change: object, input: ZMapChangeInput<K, V>): void;
|
|
19
|
-
build(): {
|
|
20
|
-
stream: Reactive<ZMap<K, V>>;
|
|
21
|
-
input: ZMapChangeInput<K, V>;
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
export declare function sink<K, V>(graph: Graph, keyIso: Iso<K, unknown>, valueIso: Iso<V, unknown>): (snapshot: object) => Sink<Reactive<ZMap<K, V>>, ZMapChangeInput<K, V>>;
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { Reactive, ZMapOperations, ZMapChangeInput } from "@derivation/composable";
|
|
2
|
-
import { zmap } from "./iso.js";
|
|
3
|
-
export class ReactiveMapSourceAdapter {
|
|
4
|
-
constructor(map, keyIso, valueIso) {
|
|
5
|
-
this.map = map;
|
|
6
|
-
this.iso = zmap(keyIso, valueIso);
|
|
7
|
-
}
|
|
8
|
-
get Snapshot() {
|
|
9
|
-
return this.iso.to(this.map.snapshot);
|
|
10
|
-
}
|
|
11
|
-
get LastChange() {
|
|
12
|
-
const change = this.iso.to(this.map.changes.value);
|
|
13
|
-
if (change.length === 0)
|
|
14
|
-
return null;
|
|
15
|
-
return change;
|
|
16
|
-
}
|
|
17
|
-
get Stream() {
|
|
18
|
-
return this.map;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
export class ReactiveMapSinkAdapter {
|
|
22
|
-
constructor(graph, keyIso, valueIso, snapshot) {
|
|
23
|
-
this.graph = graph;
|
|
24
|
-
this.iso = zmap(keyIso, valueIso);
|
|
25
|
-
this.initialMap = this.iso.from(snapshot);
|
|
26
|
-
}
|
|
27
|
-
apply(change, input) {
|
|
28
|
-
const zmapChange = this.iso.from(change);
|
|
29
|
-
for (const [key, value, weight] of zmapChange.getEntries()) {
|
|
30
|
-
input.add(key, value, weight);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
build() {
|
|
34
|
-
const input = new ZMapChangeInput(this.graph);
|
|
35
|
-
const stream = Reactive.create(this.graph, new ZMapOperations(), input, this.initialMap);
|
|
36
|
-
return { stream, input };
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
export function sink(graph, keyIso, valueIso) {
|
|
40
|
-
return (snapshot) => {
|
|
41
|
-
return new ReactiveMapSinkAdapter(graph, keyIso, valueIso, snapshot);
|
|
42
|
-
};
|
|
43
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { Graph } from "derivation";
|
|
2
|
-
import { ZSet, Reactive, ZSetChangeInput } from "@derivation/composable";
|
|
3
|
-
import { Source, Sink } from "./stream-types.js";
|
|
4
|
-
import { Iso } from "./iso.js";
|
|
5
|
-
export declare class ReactiveSetSourceAdapter<T> implements Source<Reactive<ZSet<T>>> {
|
|
6
|
-
private readonly set;
|
|
7
|
-
private readonly iso;
|
|
8
|
-
constructor(set: Reactive<ZSet<T>>, iso: Iso<T, unknown>);
|
|
9
|
-
get Snapshot(): object;
|
|
10
|
-
get LastChange(): object | null;
|
|
11
|
-
get Stream(): Reactive<ZSet<T>>;
|
|
12
|
-
}
|
|
13
|
-
export declare class ReactiveSetSinkAdapter<T> implements Sink<Reactive<ZSet<T>>, ZSetChangeInput<T>> {
|
|
14
|
-
private readonly graph;
|
|
15
|
-
private readonly iso;
|
|
16
|
-
private readonly initialSet;
|
|
17
|
-
constructor(graph: Graph, iso: Iso<ZSet<T>, unknown>, snapshot: object);
|
|
18
|
-
apply(change: object, input: ZSetChangeInput<T>): void;
|
|
19
|
-
build(): {
|
|
20
|
-
stream: Reactive<ZSet<T>>;
|
|
21
|
-
input: ZSetChangeInput<T>;
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
export declare function sink<T>(graph: Graph, iso: Iso<T, unknown>): (snapshot: object) => Sink<Reactive<ZSet<T>>, ZSetChangeInput<T>>;
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { Reactive, ZSetOperations, ZSetChangeInput } from "@derivation/composable";
|
|
2
|
-
import { zset, zsetToArray, compose } from "./iso.js";
|
|
3
|
-
export class ReactiveSetSourceAdapter {
|
|
4
|
-
constructor(set, iso) {
|
|
5
|
-
this.set = set;
|
|
6
|
-
this.iso = compose(zset(iso), zsetToArray());
|
|
7
|
-
}
|
|
8
|
-
get Snapshot() {
|
|
9
|
-
return this.iso.to(this.set.snapshot);
|
|
10
|
-
}
|
|
11
|
-
get LastChange() {
|
|
12
|
-
const change = this.iso.to(this.set.changes.value);
|
|
13
|
-
if (change.length === 0)
|
|
14
|
-
return null;
|
|
15
|
-
return change;
|
|
16
|
-
}
|
|
17
|
-
get Stream() {
|
|
18
|
-
return this.set;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
export class ReactiveSetSinkAdapter {
|
|
22
|
-
constructor(graph, iso, snapshot) {
|
|
23
|
-
this.graph = graph;
|
|
24
|
-
this.iso = iso;
|
|
25
|
-
this.initialSet = iso.from(snapshot);
|
|
26
|
-
}
|
|
27
|
-
apply(change, input) {
|
|
28
|
-
input.push(this.iso.from(change));
|
|
29
|
-
}
|
|
30
|
-
build() {
|
|
31
|
-
const input = new ZSetChangeInput(this.graph);
|
|
32
|
-
const stream = Reactive.create(this.graph, new ZSetOperations(), input, this.initialSet);
|
|
33
|
-
return { stream, input };
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
export function sink(graph, iso) {
|
|
37
|
-
const wholeIso = compose(zset(iso), zsetToArray());
|
|
38
|
-
return (snapshot) => {
|
|
39
|
-
return new ReactiveSetSinkAdapter(graph, wholeIso, snapshot);
|
|
40
|
-
};
|
|
41
|
-
}
|
package/dist/server-message.d.ts
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
export declare const HeartbeatMessageSchema: z.ZodObject<{
|
|
3
|
-
type: z.ZodLiteral<"heartbeat">;
|
|
4
|
-
}, z.core.$strip>;
|
|
5
|
-
export type HeartbeatMessage = z.infer<typeof HeartbeatMessageSchema>;
|
|
6
|
-
export declare const SubscribedSchema: z.ZodObject<{
|
|
7
|
-
type: z.ZodLiteral<"snapshot">;
|
|
8
|
-
id: z.ZodNumber;
|
|
9
|
-
snapshot: z.ZodUnknown;
|
|
10
|
-
}, z.core.$strip>;
|
|
11
|
-
export type SubscribedMessage = z.infer<typeof SubscribedSchema>;
|
|
12
|
-
export declare const DeltaMessageSchema: z.ZodObject<{
|
|
13
|
-
type: z.ZodLiteral<"delta">;
|
|
14
|
-
changes: z.ZodRecord<z.ZodNumber, z.ZodUnknown>;
|
|
15
|
-
}, z.core.$strip>;
|
|
16
|
-
export type DeltaMessage = z.infer<typeof DeltaMessageSchema>;
|
|
17
|
-
export declare const ResultMessageSchema: z.ZodObject<{
|
|
18
|
-
type: z.ZodLiteral<"result">;
|
|
19
|
-
id: z.ZodNumber;
|
|
20
|
-
success: z.ZodBoolean;
|
|
21
|
-
value: z.ZodOptional<z.ZodUnknown>;
|
|
22
|
-
error: z.ZodOptional<z.ZodString>;
|
|
23
|
-
}, z.core.$strip>;
|
|
24
|
-
export type ResultMessage = z.infer<typeof ResultMessageSchema>;
|
|
25
|
-
export declare const ServerMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
26
|
-
type: z.ZodLiteral<"heartbeat">;
|
|
27
|
-
}, z.core.$strip>, z.ZodObject<{
|
|
28
|
-
type: z.ZodLiteral<"snapshot">;
|
|
29
|
-
id: z.ZodNumber;
|
|
30
|
-
snapshot: z.ZodUnknown;
|
|
31
|
-
}, z.core.$strip>, z.ZodObject<{
|
|
32
|
-
type: z.ZodLiteral<"delta">;
|
|
33
|
-
changes: z.ZodRecord<z.ZodNumber, z.ZodUnknown>;
|
|
34
|
-
}, z.core.$strip>, z.ZodObject<{
|
|
35
|
-
type: z.ZodLiteral<"result">;
|
|
36
|
-
id: z.ZodNumber;
|
|
37
|
-
success: z.ZodBoolean;
|
|
38
|
-
value: z.ZodOptional<z.ZodUnknown>;
|
|
39
|
-
error: z.ZodOptional<z.ZodString>;
|
|
40
|
-
}, z.core.$strip>], "type">;
|
|
41
|
-
export type ServerMessage = z.infer<typeof ServerMessageSchema>;
|
|
42
|
-
export declare const ServerMessage: {
|
|
43
|
-
heartbeat: () => HeartbeatMessage;
|
|
44
|
-
subscribed: (id: number, snapshot: unknown) => SubscribedMessage;
|
|
45
|
-
delta: (changes: Record<string, unknown>) => DeltaMessage;
|
|
46
|
-
resultSuccess: (id: number, value: unknown) => ResultMessage;
|
|
47
|
-
resultError: (id: number, error: string) => ResultMessage;
|
|
48
|
-
};
|
package/dist/server-message.js
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
export const HeartbeatMessageSchema = z.object({
|
|
3
|
-
type: z.literal("heartbeat"),
|
|
4
|
-
});
|
|
5
|
-
export const SubscribedSchema = z.object({
|
|
6
|
-
type: z.literal("snapshot"),
|
|
7
|
-
id: z.number(),
|
|
8
|
-
snapshot: z.unknown(),
|
|
9
|
-
});
|
|
10
|
-
export const DeltaMessageSchema = z.object({
|
|
11
|
-
type: z.literal("delta"),
|
|
12
|
-
changes: z.record(z.number(), z.unknown()),
|
|
13
|
-
});
|
|
14
|
-
export const ResultMessageSchema = z.object({
|
|
15
|
-
type: z.literal("result"),
|
|
16
|
-
id: z.number(),
|
|
17
|
-
success: z.boolean(),
|
|
18
|
-
value: z.unknown().optional(),
|
|
19
|
-
error: z.string().optional(),
|
|
20
|
-
});
|
|
21
|
-
export const ServerMessageSchema = z.discriminatedUnion("type", [
|
|
22
|
-
HeartbeatMessageSchema,
|
|
23
|
-
SubscribedSchema,
|
|
24
|
-
DeltaMessageSchema,
|
|
25
|
-
ResultMessageSchema,
|
|
26
|
-
]);
|
|
27
|
-
export const ServerMessage = {
|
|
28
|
-
heartbeat: () => ({
|
|
29
|
-
type: "heartbeat",
|
|
30
|
-
}),
|
|
31
|
-
subscribed: (id, snapshot) => ({
|
|
32
|
-
type: "snapshot",
|
|
33
|
-
id,
|
|
34
|
-
snapshot,
|
|
35
|
-
}),
|
|
36
|
-
delta: (changes) => ({
|
|
37
|
-
type: "delta",
|
|
38
|
-
changes: changes,
|
|
39
|
-
}),
|
|
40
|
-
resultSuccess: (id, value) => ({
|
|
41
|
-
type: "result",
|
|
42
|
-
id,
|
|
43
|
-
success: true,
|
|
44
|
-
value,
|
|
45
|
-
}),
|
|
46
|
-
resultError: (id, error) => ({
|
|
47
|
-
type: "result",
|
|
48
|
-
id,
|
|
49
|
-
success: false,
|
|
50
|
-
error,
|
|
51
|
-
}),
|
|
52
|
-
};
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { ClientMessage } from "./client-message.js";
|
|
2
|
-
import { ServerMessage } from "./server-message.js";
|
|
3
|
-
import { StreamEndpoints, MutationEndpoints, RPCDefinition } from "./stream-types.js";
|
|
4
|
-
import { PresenceHandler } from "./presence-manager.js";
|
|
5
|
-
import { Transport } from "./transport.js";
|
|
6
|
-
/**
|
|
7
|
-
* Client handler for SharedWorker connections (browser-only).
|
|
8
|
-
* Simplified version without rate limiting, heartbeats, or inactivity timeouts.
|
|
9
|
-
* Designed for same-origin trusted connections.
|
|
10
|
-
*/
|
|
11
|
-
export declare class SharedWorkerClientHandler<Defs extends RPCDefinition, Ctx = void> {
|
|
12
|
-
private readonly transport;
|
|
13
|
-
private readonly context;
|
|
14
|
-
private readonly streamEndpoints;
|
|
15
|
-
private readonly mutationEndpoints;
|
|
16
|
-
private readonly presenceHandler?;
|
|
17
|
-
private currentPresence?;
|
|
18
|
-
private closed;
|
|
19
|
-
private readonly streams;
|
|
20
|
-
constructor(transport: Transport, context: Ctx, streamEndpoints: StreamEndpoints<Defs["streams"], Ctx>, mutationEndpoints: MutationEndpoints<Defs["mutations"], Ctx>, presenceHandler?: PresenceHandler);
|
|
21
|
-
handleMessage(message: string): void;
|
|
22
|
-
handleClientMessage(message: ClientMessage): Promise<void>;
|
|
23
|
-
handleStep(): void;
|
|
24
|
-
sendMessage(message: ServerMessage): void;
|
|
25
|
-
private handleDisconnect;
|
|
26
|
-
close(): void;
|
|
27
|
-
}
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
import { parseClientMessage } from "./client-message.js";
|
|
2
|
-
import { ServerMessage } from "./server-message.js";
|
|
3
|
-
/**
|
|
4
|
-
* Client handler for SharedWorker connections (browser-only).
|
|
5
|
-
* Simplified version without rate limiting, heartbeats, or inactivity timeouts.
|
|
6
|
-
* Designed for same-origin trusted connections.
|
|
7
|
-
*/
|
|
8
|
-
export class SharedWorkerClientHandler {
|
|
9
|
-
constructor(transport, context, streamEndpoints, mutationEndpoints, presenceHandler) {
|
|
10
|
-
this.closed = false;
|
|
11
|
-
this.streams = new Map();
|
|
12
|
-
this.transport = transport;
|
|
13
|
-
this.context = context;
|
|
14
|
-
this.streamEndpoints = streamEndpoints;
|
|
15
|
-
this.mutationEndpoints = mutationEndpoints;
|
|
16
|
-
this.presenceHandler = presenceHandler;
|
|
17
|
-
console.log("new client connected");
|
|
18
|
-
// Set up transport handlers
|
|
19
|
-
this.transport.onMessage((data) => this.handleMessage(data));
|
|
20
|
-
this.transport.onClose(() => this.handleDisconnect());
|
|
21
|
-
}
|
|
22
|
-
handleMessage(message) {
|
|
23
|
-
let data;
|
|
24
|
-
try {
|
|
25
|
-
data = JSON.parse(message);
|
|
26
|
-
}
|
|
27
|
-
catch (_a) {
|
|
28
|
-
console.error("Invalid JSON received:", message);
|
|
29
|
-
return this.close();
|
|
30
|
-
}
|
|
31
|
-
let parsed;
|
|
32
|
-
try {
|
|
33
|
-
parsed = parseClientMessage(data);
|
|
34
|
-
}
|
|
35
|
-
catch (error) {
|
|
36
|
-
console.error("Invalid client message:", error);
|
|
37
|
-
return this.close();
|
|
38
|
-
}
|
|
39
|
-
this.handleClientMessage(parsed);
|
|
40
|
-
}
|
|
41
|
-
async handleClientMessage(message) {
|
|
42
|
-
switch (message.type) {
|
|
43
|
-
case "subscribe": {
|
|
44
|
-
const { id, name, args } = message;
|
|
45
|
-
if (!(name in this.streamEndpoints)) {
|
|
46
|
-
console.error(`Unknown stream: ${name}`);
|
|
47
|
-
this.close();
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
const endpoint = this.streamEndpoints[name];
|
|
51
|
-
try {
|
|
52
|
-
const source = await endpoint(args, this.context);
|
|
53
|
-
this.streams.set(id, source);
|
|
54
|
-
this.sendMessage(ServerMessage.subscribed(id, source.Snapshot));
|
|
55
|
-
console.log(`Client subscribed to "${name}" (${id})`);
|
|
56
|
-
}
|
|
57
|
-
catch (err) {
|
|
58
|
-
console.error(`Error building stream ${name}:`, err);
|
|
59
|
-
this.close();
|
|
60
|
-
}
|
|
61
|
-
break;
|
|
62
|
-
}
|
|
63
|
-
case "unsubscribe": {
|
|
64
|
-
const { id } = message;
|
|
65
|
-
this.streams.delete(id);
|
|
66
|
-
console.log(`Client unsubscribed from ${id}`);
|
|
67
|
-
break;
|
|
68
|
-
}
|
|
69
|
-
case "call": {
|
|
70
|
-
const { id, name, args } = message;
|
|
71
|
-
if (!(name in this.mutationEndpoints)) {
|
|
72
|
-
console.error(`Unknown mutation: ${name}`);
|
|
73
|
-
this.close();
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
const endpoint = this.mutationEndpoints[name];
|
|
77
|
-
endpoint(args, this.context)
|
|
78
|
-
.then((result) => {
|
|
79
|
-
if (result.success) {
|
|
80
|
-
this.sendMessage(ServerMessage.resultSuccess(id, result.value));
|
|
81
|
-
console.log(`Mutation "${name}" (${id}) completed successfully`);
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
this.sendMessage(ServerMessage.resultError(id, result.error));
|
|
85
|
-
console.log(`Mutation "${name}" (${id}) returned error: ${result.error}`);
|
|
86
|
-
}
|
|
87
|
-
})
|
|
88
|
-
.catch((err) => {
|
|
89
|
-
console.error(`Unhandled exception in mutation "${name}" (${id}):`, err);
|
|
90
|
-
this.close();
|
|
91
|
-
});
|
|
92
|
-
break;
|
|
93
|
-
}
|
|
94
|
-
case "heartbeat":
|
|
95
|
-
break;
|
|
96
|
-
case "presence": {
|
|
97
|
-
if (!this.presenceHandler) {
|
|
98
|
-
console.error("Presence not configured");
|
|
99
|
-
this.close();
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
const { data } = message;
|
|
103
|
-
if (this.currentPresence !== undefined) {
|
|
104
|
-
this.presenceHandler.update(this.currentPresence, data);
|
|
105
|
-
}
|
|
106
|
-
else {
|
|
107
|
-
this.presenceHandler.add(data);
|
|
108
|
-
}
|
|
109
|
-
this.currentPresence = data;
|
|
110
|
-
break;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
handleStep() {
|
|
115
|
-
if (this.closed)
|
|
116
|
-
return;
|
|
117
|
-
const changes = {};
|
|
118
|
-
for (const [id, source] of this.streams) {
|
|
119
|
-
const change = source.LastChange;
|
|
120
|
-
if (change === null)
|
|
121
|
-
continue;
|
|
122
|
-
changes[id] = change;
|
|
123
|
-
}
|
|
124
|
-
if (Object.keys(changes).length > 0) {
|
|
125
|
-
this.sendMessage(ServerMessage.delta(changes));
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
sendMessage(message) {
|
|
129
|
-
if (this.closed)
|
|
130
|
-
return;
|
|
131
|
-
this.transport.send(JSON.stringify(message));
|
|
132
|
-
}
|
|
133
|
-
handleDisconnect() {
|
|
134
|
-
this.close();
|
|
135
|
-
}
|
|
136
|
-
close() {
|
|
137
|
-
if (this.closed)
|
|
138
|
-
return;
|
|
139
|
-
this.closed = true;
|
|
140
|
-
if (this.presenceHandler && this.currentPresence) {
|
|
141
|
-
this.presenceHandler.remove(this.currentPresence);
|
|
142
|
-
}
|
|
143
|
-
this.streams.clear();
|
|
144
|
-
try {
|
|
145
|
-
this.transport.close();
|
|
146
|
-
}
|
|
147
|
-
catch (_a) { }
|
|
148
|
-
}
|
|
149
|
-
}
|
package/dist/stream-adapter.d.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { Graph, ReactiveValue, Input } from "derivation";
|
|
2
|
-
import { Source, Sink } from "./stream-types.js";
|
|
3
|
-
import { Iso } from "./iso.js";
|
|
4
|
-
export declare class StreamSourceAdapter<T extends object> implements Source<ReactiveValue<T>> {
|
|
5
|
-
private readonly stream;
|
|
6
|
-
private readonly iso;
|
|
7
|
-
constructor(stream: ReactiveValue<T>, iso: Iso<T, object>);
|
|
8
|
-
get Snapshot(): object;
|
|
9
|
-
get LastChange(): object | null;
|
|
10
|
-
get Stream(): ReactiveValue<T>;
|
|
11
|
-
}
|
|
12
|
-
export declare class StreamSinkAdapter<T extends object> implements Sink<Input<T>, Input<T>> {
|
|
13
|
-
private readonly graph;
|
|
14
|
-
private readonly iso;
|
|
15
|
-
private readonly initialValue;
|
|
16
|
-
constructor(graph: Graph, iso: Iso<T, object>, snapshot: object);
|
|
17
|
-
apply(change: object, input: Input<T>): void;
|
|
18
|
-
build(): {
|
|
19
|
-
stream: Input<T>;
|
|
20
|
-
input: Input<T>;
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
export declare function sink<T extends object>(graph: Graph, iso: Iso<T, object>): (snapshot: object) => Sink<Input<T>, Input<T>>;
|
package/dist/stream-adapter.js
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { inputValue } from "derivation";
|
|
2
|
-
export class StreamSourceAdapter {
|
|
3
|
-
constructor(stream, iso) {
|
|
4
|
-
this.stream = stream;
|
|
5
|
-
this.iso = iso;
|
|
6
|
-
}
|
|
7
|
-
get Snapshot() {
|
|
8
|
-
return this.iso.to(this.stream.value);
|
|
9
|
-
}
|
|
10
|
-
get LastChange() {
|
|
11
|
-
return this.iso.to(this.stream.value);
|
|
12
|
-
}
|
|
13
|
-
get Stream() {
|
|
14
|
-
return this.stream;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
export class StreamSinkAdapter {
|
|
18
|
-
constructor(graph, iso, snapshot) {
|
|
19
|
-
this.graph = graph;
|
|
20
|
-
this.iso = iso;
|
|
21
|
-
this.initialValue = iso.from(snapshot);
|
|
22
|
-
}
|
|
23
|
-
apply(change, input) {
|
|
24
|
-
input.push(this.iso.from(change));
|
|
25
|
-
}
|
|
26
|
-
build() {
|
|
27
|
-
const stream = inputValue(this.graph, this.initialValue);
|
|
28
|
-
return { stream, input: stream };
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
export function sink(graph, iso) {
|
|
32
|
-
return (snapshot) => {
|
|
33
|
-
return new StreamSinkAdapter(graph, iso, snapshot);
|
|
34
|
-
};
|
|
35
|
-
}
|
package/dist/stream-types.d.ts
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
export interface Source<ReturnType> {
|
|
2
|
-
get Snapshot(): object;
|
|
3
|
-
get LastChange(): object | null;
|
|
4
|
-
get Stream(): ReturnType;
|
|
5
|
-
}
|
|
6
|
-
export interface Sink<SinkType, InputType> {
|
|
7
|
-
apply(change: object, input: InputType): void;
|
|
8
|
-
build(): {
|
|
9
|
-
stream: SinkType;
|
|
10
|
-
input: InputType;
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
export type StreamDefinition<Args extends object, ReturnType extends object, SinkType extends ReturnType, InputType extends object> = {
|
|
14
|
-
args: Args;
|
|
15
|
-
returnType: ReturnType;
|
|
16
|
-
sinkType: SinkType;
|
|
17
|
-
inputType: InputType;
|
|
18
|
-
};
|
|
19
|
-
export type StreamDefinitions = Record<string, StreamDefinition<object, object, object, object>>;
|
|
20
|
-
export type StreamEndpoints<Definitions extends StreamDefinitions, Ctx = void> = {
|
|
21
|
-
[K in keyof Definitions]: (args: Definitions[K]["args"], ctx: Ctx) => Promise<Source<Definitions[K]["returnType"]>>;
|
|
22
|
-
};
|
|
23
|
-
export type StreamSinks<Definitions extends StreamDefinitions> = {
|
|
24
|
-
[K in keyof Definitions]: (snapshot: object) => Sink<Definitions[K]["sinkType"], Definitions[K]["inputType"]>;
|
|
25
|
-
};
|
|
26
|
-
export type MutationResult<T> = {
|
|
27
|
-
success: true;
|
|
28
|
-
value: T;
|
|
29
|
-
} | {
|
|
30
|
-
success: false;
|
|
31
|
-
error: string;
|
|
32
|
-
};
|
|
33
|
-
export type MutationDefinition<Args, Result> = {
|
|
34
|
-
args: Args;
|
|
35
|
-
result: Result;
|
|
36
|
-
};
|
|
37
|
-
export type MutationDefinitions = Record<string, MutationDefinition<unknown, unknown>>;
|
|
38
|
-
export type MutationEndpoints<Definitions extends MutationDefinitions, Ctx = void> = {
|
|
39
|
-
[K in keyof Definitions]: (args: Definitions[K]["args"], ctx: Ctx) => Promise<MutationResult<Definitions[K]["result"]>>;
|
|
40
|
-
};
|
|
41
|
-
export type RPCDefinition = {
|
|
42
|
-
streams: StreamDefinitions;
|
|
43
|
-
mutations: MutationDefinitions;
|
|
44
|
-
};
|
package/dist/stream-types.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|