@shivaedev/effect-contract 0.10.0 → 0.12.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/CHANGELOG.md +27 -0
- package/README.md +33 -10
- package/dist/automaticLive.d.ts +9 -7
- package/dist/automaticLive.d.ts.map +1 -1
- package/dist/automaticLive.js +52 -19
- package/dist/automaticLive.js.map +1 -1
- package/dist/bind.d.ts +11 -7
- package/dist/bind.d.ts.map +1 -1
- package/dist/bind.js +9 -36
- package/dist/bind.js.map +1 -1
- package/dist/contract.d.ts +13 -8
- package/dist/contract.d.ts.map +1 -1
- package/dist/contract.js +19 -9
- package/dist/contract.js.map +1 -1
- package/dist/internal/bindingOwner.d.ts +8 -0
- package/dist/internal/bindingOwner.d.ts.map +1 -0
- package/dist/internal/bindingOwner.js +16 -0
- package/dist/internal/bindingOwner.js.map +1 -0
- package/dist/internal/clientOperations.d.ts +21 -0
- package/dist/internal/clientOperations.d.ts.map +1 -0
- package/dist/internal/clientOperations.js +36 -0
- package/dist/internal/clientOperations.js.map +1 -0
- package/dist/internal/queryReactivity.d.ts +2 -1
- package/dist/internal/queryReactivity.d.ts.map +1 -1
- package/dist/internal/queryReactivity.js +5 -1
- package/dist/internal/queryReactivity.js.map +1 -1
- package/dist/keys.d.ts +5 -2
- package/dist/keys.d.ts.map +1 -1
- package/dist/keys.js +7 -4
- package/dist/keys.js.map +1 -1
- package/dist/live.d.ts +4 -2
- package/dist/live.d.ts.map +1 -1
- package/dist/live.js +5 -4
- package/dist/live.js.map +1 -1
- package/dist/makeLiveServer.d.ts +2 -2
- package/dist/makeLiveServer.d.ts.map +1 -1
- package/dist/makeLiveServer.js +3 -3
- package/dist/makeLiveServer.js.map +1 -1
- package/dist/operation.d.ts +1 -1
- package/dist/serverMetadata.d.ts +21 -12
- package/dist/serverMetadata.d.ts.map +1 -1
- package/dist/serverMetadata.js +19 -4
- package/dist/serverMetadata.js.map +1 -1
- package/package.json +12 -12
- package/src/automaticLive.ts +64 -24
- package/src/bind.ts +21 -54
- package/src/contract.ts +43 -17
- package/src/internal/bindingOwner.ts +24 -0
- package/src/internal/clientOperations.ts +74 -0
- package/src/internal/queryReactivity.ts +11 -1
- package/src/keys.ts +16 -4
- package/src/live.ts +8 -5
- package/src/makeLiveServer.ts +4 -4
- package/src/operation.ts +1 -1
- package/src/serverMetadata.ts +40 -5
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Effect, Stream } from "effect";
|
|
2
|
+
import * as AtomRegistry from "effect/reactivity/AtomRegistry";
|
|
3
|
+
import * as Reactivity from "effect/reactivity/Reactivity";
|
|
4
|
+
import { invalidationKeys, readKeys } from "#keys.ts";
|
|
5
|
+
import { queryReactivity } from "./queryReactivity.js";
|
|
6
|
+
function run(service, effect, owner) {
|
|
7
|
+
return owner === undefined ? effect : Effect.suspend(() => AtomRegistry.getResult(owner.registry, service.runtime.atom(effect)));
|
|
8
|
+
}
|
|
9
|
+
export function boundQuery(service, tag, query, track, owner) {
|
|
10
|
+
const reactive = queryReactivity(service.runtime);
|
|
11
|
+
return {
|
|
12
|
+
query: (payload, options = {}) => {
|
|
13
|
+
const atom = service.query(tag, payload, options);
|
|
14
|
+
const keys = query.reads(payload);
|
|
15
|
+
const reference = { payload, query: query.name };
|
|
16
|
+
if (owner === undefined) {
|
|
17
|
+
track(undefined, reference, keys);
|
|
18
|
+
}
|
|
19
|
+
return reactive(atom, readKeys(keys, owner?.context), (registry) => (owner === undefined ? () => undefined : track(registry, reference, keys)), owner?.registry);
|
|
20
|
+
},
|
|
21
|
+
run: (payload) => run(service, service.use((client) => client(tag, payload)), owner),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export function boundCommand(service, tag, command, owner) {
|
|
25
|
+
return {
|
|
26
|
+
run: (payload) => run(service, service
|
|
27
|
+
.use((client) => client(tag, payload))
|
|
28
|
+
.pipe(Effect.tap((result) => Reactivity.invalidate(invalidationKeys(command.invalidates(payload, result), owner?.context)))), owner),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export function boundStream(service, tag) {
|
|
32
|
+
return {
|
|
33
|
+
run: (payload) => Stream.unwrap(service.use((client) => Effect.succeed(client(tag, payload)))),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=clientOperations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clientOperations.js","sourceRoot":"","sources":["../../src/internal/clientOperations.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as AsyncResult from "effect/reactivity/AsyncResult";
|
|
2
2
|
import * as Atom from "effect/reactivity/Atom";
|
|
3
|
-
|
|
3
|
+
import type * as AtomRegistry from "effect/reactivity/AtomRegistry";
|
|
4
|
+
export declare function queryReactivity<R, E>(runtime: Atom.AtomRuntime<R, E>): (atom: Atom.Atom<AsyncResult.AsyncResult<unknown, unknown>>, keys: readonly string[], track: (registry: AtomRegistry.AtomRegistry) => () => void, owner?: AtomRegistry.AtomRegistry) => Atom.Atom<AsyncResult.AsyncResult<unknown, unknown>>;
|
|
4
5
|
//# sourceMappingURL=queryReactivity.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queryReactivity.d.ts","sourceRoot":"","sources":["../../src/internal/queryReactivity.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,WAAW,MAAM,+BAA+B,CAAC;AAC7D,OAAO,KAAK,IAAI,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"queryReactivity.d.ts","sourceRoot":"","sources":["../../src/internal/queryReactivity.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,WAAW,MAAM,+BAA+B,CAAC;AAC7D,OAAO,KAAK,IAAI,MAAM,wBAAwB,CAAC;AAC/C,OAAO,KAAK,KAAK,YAAY,MAAM,gCAAgC,CAAC;AAKpE,wBAAgB,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,sEAM7D,SAAS,MAAM,EAAE,SAChB,CAAC,QAAQ,EAAE,YAAY,CAAC,YAAY,KAAK,MAAM,IAAI,UAClD,YAAY,CAAC,YAAY,0DA4FlC"}
|
|
@@ -7,18 +7,22 @@ import { liveBatches, liveKeys } from "./liveInvalidation.js";
|
|
|
7
7
|
export function queryReactivity(runtime) {
|
|
8
8
|
const service = runtime.atom(Effect.service(Reactivity.Reactivity));
|
|
9
9
|
const cached = new WeakMap();
|
|
10
|
-
return (atom, keys) => {
|
|
10
|
+
return (atom, keys, track, owner) => {
|
|
11
11
|
const existing = cached.get(atom);
|
|
12
12
|
if (existing !== undefined) {
|
|
13
13
|
return existing;
|
|
14
14
|
}
|
|
15
15
|
const source = Atom.setIdleTTL(Atom.readable((get) => atom.read(get), atom.refresh), 0);
|
|
16
16
|
let wrapped = Atom.transform(source, (get) => {
|
|
17
|
+
if (owner !== undefined && owner !== get.registry) {
|
|
18
|
+
throw new Error("A session-scoped query belongs to its binding registry");
|
|
19
|
+
}
|
|
17
20
|
const context = get(service);
|
|
18
21
|
if (!AsyncResult.isSuccess(context)) {
|
|
19
22
|
return get(source);
|
|
20
23
|
}
|
|
21
24
|
const reactivity = context.value;
|
|
25
|
+
get.addFinalizer(track(get.registry));
|
|
22
26
|
let pending;
|
|
23
27
|
let timer;
|
|
24
28
|
function clear() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queryReactivity.js","sourceRoot":"","sources":["../../src/internal/queryReactivity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC1C,OAAO,KAAK,WAAW,MAAM,+BAA+B,CAAC;AAC7D,OAAO,KAAK,IAAI,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"queryReactivity.js","sourceRoot":"","sources":["../../src/internal/queryReactivity.ts"],"names":[],"mappings":"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"}
|
package/dist/keys.d.ts
CHANGED
|
@@ -26,6 +26,9 @@ export interface Collection<TName extends string, TId extends Identity> {
|
|
|
26
26
|
export declare function collection<const TName extends string, TId extends Schema.Top & {
|
|
27
27
|
readonly Type: Identity;
|
|
28
28
|
}>(name: TName, _id: TId): Collection<TName, TId["Type"]>;
|
|
29
|
-
export
|
|
30
|
-
|
|
29
|
+
export interface KeyContext {
|
|
30
|
+
readonly scope: string;
|
|
31
|
+
}
|
|
32
|
+
export declare function readKeys(keys: readonly Key[], context?: KeyContext): readonly string[];
|
|
33
|
+
export declare function invalidationKeys(keys: readonly Key[], context?: KeyContext): readonly string[];
|
|
31
34
|
//# sourceMappingURL=keys.d.ts.map
|
package/dist/keys.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../src/keys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;AAEvC,MAAM,WAAW,OAAO,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM;IACrD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAC;CAC3B;AAED,MAAM,WAAW,OAAO,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM;IACrD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAC;IAC3B,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC;CACtB;AAED,MAAM,MAAM,GAAG,GAAG,OAAO,GAAG,OAAO,CAAC;AAEpC,eAAO,MAAM,GAAG;;;;;;;IAGd,CAAC;AAEH,MAAM,WAAW,UAAU,CAAC,KAAK,SAAS,MAAM,EAAE,GAAG,SAAS,QAAQ;IACrE,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,GAAG,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC;IAC3C,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;CACrB;AAED,wBAAgB,UAAU,CAAC,KAAK,CAAC,KAAK,SAAS,MAAM,EAAE,GAAG,SAAS,MAAM,CAAC,GAAG,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,EAC1G,IAAI,EAAE,KAAK,EACX,GAAG,EAAE,GAAG,GACN,UAAU,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAMhC;
|
|
1
|
+
{"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../src/keys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;AAEvC,MAAM,WAAW,OAAO,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM;IACrD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAC;CAC3B;AAED,MAAM,WAAW,OAAO,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM;IACrD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAC;IAC3B,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC;CACtB;AAED,MAAM,MAAM,GAAG,GAAG,OAAO,GAAG,OAAO,CAAC;AAEpC,eAAO,MAAM,GAAG;;;;;;;IAGd,CAAC;AAEH,MAAM,WAAW,UAAU,CAAC,KAAK,SAAS,MAAM,EAAE,GAAG,SAAS,QAAQ;IACrE,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,GAAG,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC;IAC3C,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;CACrB;AAED,wBAAgB,UAAU,CAAC,KAAK,CAAC,KAAK,SAAS,MAAM,EAAE,GAAG,SAAS,MAAM,CAAC,GAAG,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,EAC1G,IAAI,EAAE,KAAK,EACX,GAAG,EAAE,GAAG,GACN,UAAU,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAMhC;AAED,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACvB;AAUD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,EAAE,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,SAAS,MAAM,EAAE,CAItF;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,GAAG,EAAE,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,SAAS,MAAM,EAAE,CAI9F"}
|
package/dist/keys.js
CHANGED
|
@@ -10,13 +10,16 @@ export function collection(name, _id) {
|
|
|
10
10
|
name,
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
|
+
function contextual(key, context) {
|
|
14
|
+
return context === undefined ? key : `${JSON.stringify(["session", context.scope])}:${key}`;
|
|
15
|
+
}
|
|
13
16
|
function own(key) {
|
|
14
17
|
return key._tag === "List" ? key.collection : `${key.collection}:${key.id}`;
|
|
15
18
|
}
|
|
16
|
-
export function readKeys(keys) {
|
|
17
|
-
return [...new Set(keys.
|
|
19
|
+
export function readKeys(keys, context) {
|
|
20
|
+
return [...new Set(keys.flatMap((key) => (key._tag === "Item" ? [own(key), `${key.collection}:*`] : [own(key)])))].map((key) => contextual(key, context));
|
|
18
21
|
}
|
|
19
|
-
export function invalidationKeys(keys) {
|
|
20
|
-
return [...new Set(keys.flatMap((key) => (key._tag === "List" ? [key.collection] : [own(key), key.collection])))];
|
|
22
|
+
export function invalidationKeys(keys, context) {
|
|
23
|
+
return [...new Set(keys.flatMap((key) => (key._tag === "List" ? [key.collection] : [own(key), key.collection])))].map((key) => contextual(key, context));
|
|
21
24
|
}
|
|
22
25
|
//# sourceMappingURL=keys.js.map
|
package/dist/keys.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keys.js","sourceRoot":"","sources":["../src/keys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAiBhC,MAAM,CAAC,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC;IAC/B,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;IAC1E,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;CAC5H,CAAC,CAAC;AAQH,MAAM,UAAU,UAAU,CACzB,IAAW,EACX,GAAQ;IAER,OAAO;QACN,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QACtD,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE;QACxC,IAAI;KACJ,CAAC;AACH,CAAC;AAED,SAAS,GAAG,CAAC,GAAQ;IACpB,OAAO,GAAG,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC;AAC7E,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAoB;
|
|
1
|
+
{"version":3,"file":"keys.js","sourceRoot":"","sources":["../src/keys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAiBhC,MAAM,CAAC,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC;IAC/B,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;IAC1E,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;CAC5H,CAAC,CAAC;AAQH,MAAM,UAAU,UAAU,CACzB,IAAW,EACX,GAAQ;IAER,OAAO;QACN,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QACtD,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE;QACxC,IAAI;KACJ,CAAC;AACH,CAAC;AAMD,SAAS,UAAU,CAAC,GAAW,EAAE,OAAoB;IACpD,OAAO,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC;AAC7F,CAAC;AAED,SAAS,GAAG,CAAC,GAAQ;IACpB,OAAO,GAAG,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC;AAC7E,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAoB,EAAE,OAAoB;IAClE,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAC9H,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CACxB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAoB,EAAE,OAAoB;IAC1E,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAC7H,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CACxB,CAAC;AACH,CAAC"}
|
package/dist/live.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type Cause, Duration, Option, Schema, Stream } from "effect";
|
|
2
2
|
import * as Atom from "effect/reactivity/Atom";
|
|
3
|
-
import
|
|
3
|
+
import type * as AtomRegistry from "effect/reactivity/AtomRegistry";
|
|
4
|
+
import { Key, type KeyContext } from "#keys.ts";
|
|
4
5
|
export declare const LiveHint: Schema.Union<readonly [Schema.Struct<{
|
|
5
6
|
readonly _tag: Schema.Literal<"Changed">;
|
|
6
7
|
readonly keys: Schema.$Array<Schema.Union<readonly [Schema.Struct<{
|
|
@@ -23,8 +24,9 @@ export interface LiveStatus<E> {
|
|
|
23
24
|
}
|
|
24
25
|
export interface LiveOptions<E, R> {
|
|
25
26
|
readonly coalesceWindow?: Duration.Input;
|
|
27
|
+
readonly keyContext?: KeyContext | undefined;
|
|
26
28
|
readonly resume?: Atom.Atom<unknown>;
|
|
27
|
-
readonly resyncKeys: readonly Key[] | (() => readonly Key[]);
|
|
29
|
+
readonly resyncKeys: readonly Key[] | ((registry: AtomRegistry.AtomRegistry) => readonly Key[]);
|
|
28
30
|
readonly retryDelay?: Duration.Input;
|
|
29
31
|
readonly stream: Stream.Stream<LiveHint, E, R>;
|
|
30
32
|
}
|
package/dist/live.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"live.d.ts","sourceRoot":"","sources":["../src/live.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,KAAK,EAAE,QAAQ,EAAU,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9E,OAAO,KAAK,IAAI,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"live.d.ts","sourceRoot":"","sources":["../src/live.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,KAAK,EAAE,QAAQ,EAAU,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9E,OAAO,KAAK,IAAI,MAAM,wBAAwB,CAAC;AAC/C,OAAO,KAAK,KAAK,YAAY,MAAM,gCAAgC,CAAC;AAGpE,OAAO,EAAoB,GAAG,EAAE,KAAK,UAAU,EAAY,MAAM,UAAU,CAAC;AAE5E,eAAO,MAAM,QAAQ;;;;;;;;;;;;IAGnB,CAAC;AACH,MAAM,MAAM,QAAQ,GAAG,OAAO,QAAQ,CAAC,IAAI,CAAC;AAC5C,MAAM,WAAW,UAAU,CAAC,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,YAAY,GAAG,MAAM,GAAG,cAAc,CAAC;IAC5D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CACzB;AACD,MAAM,WAAW,WAAW,CAAC,CAAC,EAAE,CAAC;IAChC,QAAQ,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC;IACzC,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACrC,QAAQ,CAAC,UAAU,EAAE,SAAS,GAAG,EAAE,GAAG,CAAC,CAAC,QAAQ,EAAE,YAAY,CAAC,YAAY,KAAK,SAAS,GAAG,EAAE,CAAC,CAAC;IAChG,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;CAC/C;AAID,wBAAgB,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,EAAE,aAAa,CAAC,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC;;;;;EA4FhH"}
|
package/dist/live.js
CHANGED
|
@@ -2,7 +2,7 @@ import { Duration, Effect, Option, Schema, Stream } from "effect";
|
|
|
2
2
|
import * as Atom from "effect/reactivity/Atom";
|
|
3
3
|
import * as Reactivity from "effect/reactivity/Reactivity";
|
|
4
4
|
import { invalidateLive } from "#internal/liveInvalidation.ts";
|
|
5
|
-
import { invalidationKeys, Key, readKeys } from "
|
|
5
|
+
import { invalidationKeys, Key, readKeys } from "#keys.ts";
|
|
6
6
|
export const LiveHint = Schema.Union([
|
|
7
7
|
Schema.Struct({ _tag: Schema.Literal("Changed"), keys: Schema.Array(Key) }),
|
|
8
8
|
Schema.Struct({ _tag: Schema.Literal("Resync") }),
|
|
@@ -33,14 +33,14 @@ export function live(runtime, options) {
|
|
|
33
33
|
});
|
|
34
34
|
function changed(changedKeys) {
|
|
35
35
|
const window = get.once(coalesceWindow);
|
|
36
|
-
const keys = invalidationKeys(changedKeys);
|
|
36
|
+
const keys = invalidationKeys(changedKeys, options.keyContext);
|
|
37
37
|
invalidateLive(reactivity, keys, () => active && !get.once(paused), window);
|
|
38
38
|
const delay = Duration.toMillis(Duration.fromInputUnsafe(window));
|
|
39
39
|
if (delay === 0) {
|
|
40
40
|
invalidateLive(reactivity, keys, () => active && !get.once(paused));
|
|
41
41
|
return;
|
|
42
42
|
}
|
|
43
|
-
for (const key of invalidationKeys(changedKeys)) {
|
|
43
|
+
for (const key of invalidationKeys(changedKeys, options.keyContext)) {
|
|
44
44
|
pending.add(key);
|
|
45
45
|
}
|
|
46
46
|
timer ??= setTimeout(() => {
|
|
@@ -57,7 +57,8 @@ export function live(runtime, options) {
|
|
|
57
57
|
update({ needsResync: true });
|
|
58
58
|
return;
|
|
59
59
|
}
|
|
60
|
-
|
|
60
|
+
const keys = typeof options.resyncKeys === "function" ? options.resyncKeys(get.registry) : options.resyncKeys;
|
|
61
|
+
reactivity.invalidateUnsafe(keys.map((key) => readKeys([key], options.keyContext)[0] ?? ""));
|
|
61
62
|
update({ needsResync: false, pending: 0 });
|
|
62
63
|
}
|
|
63
64
|
// A subscription alone does not build the flag, so its first read would otherwise announce a change.
|
package/dist/live.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"live.js","sourceRoot":"","sources":["../src/live.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9E,OAAO,KAAK,IAAI,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"live.js","sourceRoot":"","sources":["../src/live.ts"],"names":[],"mappings":"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"}
|
package/dist/makeLiveServer.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Effect, Stream } from "effect";
|
|
2
2
|
import * as Reactivity from "effect/reactivity/Reactivity";
|
|
3
|
-
import { type Key } from "
|
|
3
|
+
import { type Key, type KeyContext } from "#keys.ts";
|
|
4
4
|
export declare const makeLiveServer: Effect.Effect<{
|
|
5
5
|
resync: Effect.Effect<void, never, never>;
|
|
6
|
-
stream: (keys: readonly Key[]) => Stream.Stream<{
|
|
6
|
+
stream: (keys: readonly Key[], context?: KeyContext) => Stream.Stream<{
|
|
7
7
|
readonly _tag: "Changed";
|
|
8
8
|
readonly keys: readonly ({
|
|
9
9
|
readonly _tag: "List";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"makeLiveServer.d.ts","sourceRoot":"","sources":["../src/makeLiveServer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAS,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC/C,OAAO,KAAK,UAAU,MAAM,8BAA8B,CAAC;AAE3D,OAAO,EAAE,KAAK,GAAG,EAAY,MAAM,
|
|
1
|
+
{"version":3,"file":"makeLiveServer.d.ts","sourceRoot":"","sources":["../src/makeLiveServer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAS,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC/C,OAAO,KAAK,UAAU,MAAM,8BAA8B,CAAC;AAE3D,OAAO,EAAE,KAAK,GAAG,EAAE,KAAK,UAAU,EAAY,MAAM,UAAU,CAAC;AAG/D,eAAO,MAAM,cAAc;;mBAGJ,SAAS,GAAG,EAAE,YAAY,UAAU;;;;;;;;;;;;;gCA8DzD,CAAC"}
|
package/dist/makeLiveServer.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Effect, Queue, Stream } from "effect";
|
|
2
2
|
import * as Reactivity from "effect/reactivity/Reactivity";
|
|
3
3
|
import { makeHintPolicy } from "#internal/makeHintPolicy.ts";
|
|
4
|
-
import { readKeys } from "
|
|
4
|
+
import { readKeys } from "#keys.ts";
|
|
5
5
|
export const makeLiveServer = Effect.gen(function* () {
|
|
6
6
|
const reactivity = yield* Reactivity.Reactivity;
|
|
7
7
|
const resyncKey = `@shivaedev/effect-contract/resync/${crypto.randomUUID()}`;
|
|
8
|
-
function stream(keys) {
|
|
8
|
+
function stream(keys, context) {
|
|
9
9
|
return Stream.unwrap(Effect.gen(function* () {
|
|
10
10
|
const queue = yield* Queue.unbounded();
|
|
11
11
|
const allowedKeys = yield* makeHintPolicy(keys.length, (retryKeys) => Queue.offer(queue, { _tag: "Changed", keys: retryKeys }).pipe(Effect.asVoid));
|
|
@@ -28,7 +28,7 @@ export const makeLiveServer = Effect.gen(function* () {
|
|
|
28
28
|
});
|
|
29
29
|
}
|
|
30
30
|
const cancel = keys.map((key) => {
|
|
31
|
-
const own = readKeys([key]);
|
|
31
|
+
const own = readKeys([key], context);
|
|
32
32
|
return reactivity.registerUnsafe(own, () => {
|
|
33
33
|
pending.set(own[0] ?? "", key);
|
|
34
34
|
flush();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"makeLiveServer.js","sourceRoot":"","sources":["../src/makeLiveServer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC/C,OAAO,KAAK,UAAU,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,
|
|
1
|
+
{"version":3,"file":"makeLiveServer.js","sourceRoot":"","sources":["../src/makeLiveServer.ts"],"names":[],"mappings":"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"}
|
package/dist/operation.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Schema } from "effect";
|
|
2
|
-
import type { Bivariant } from "@shivaedev/types/
|
|
2
|
+
import type { Bivariant } from "@shivaedev/types/Bivariant.ts";
|
|
3
3
|
import type { Key } from "./keys.ts";
|
|
4
4
|
import { type MatchingTags, type Reject, type RejectionSpecs, type Rejections, type RejectionUnion } from "./rejection.ts";
|
|
5
5
|
export type PayloadSchema<TPayload extends Schema.Top | Schema.Struct.Fields> = TPayload extends Schema.Struct.Fields ? Schema.Struct<TPayload> : TPayload;
|
package/dist/serverMetadata.d.ts
CHANGED
|
@@ -1,21 +1,30 @@
|
|
|
1
1
|
import { Context, Schema } from "effect";
|
|
2
2
|
import { Rpc } from "effect/rpc";
|
|
3
|
-
import { Key } from "
|
|
4
|
-
|
|
3
|
+
import type { Key } from "#keys.ts";
|
|
4
|
+
import type { QueryShape } from "#operation.ts";
|
|
5
|
+
declare const QueryReads_base: Context.ServiceClass<QueryReads, "@shivaedev/effect-contract/QueryReads", import("@shivaedev/types/Bivariant.ts").Bivariant<(payload: unknown) => readonly Key[]>>;
|
|
5
6
|
export declare class QueryReads extends QueryReads_base {
|
|
6
7
|
}
|
|
7
|
-
declare const CommandInvalidation_base: Context.ServiceClass<CommandInvalidation, "@shivaedev/effect-contract/CommandInvalidation", import("@shivaedev/types/
|
|
8
|
+
declare const CommandInvalidation_base: Context.ServiceClass<CommandInvalidation, "@shivaedev/effect-contract/CommandInvalidation", import("@shivaedev/types/Bivariant.ts").Bivariant<(payload: unknown, result: unknown) => readonly Key[]>>;
|
|
8
9
|
export declare class CommandInvalidation extends CommandInvalidation_base {
|
|
9
10
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
11
|
+
declare const KeyScope_base: Context.ServiceClass<KeyScope, "@shivaedev/effect-contract/KeyScope", "session">;
|
|
12
|
+
export declare class KeyScope extends KeyScope_base {
|
|
13
|
+
}
|
|
14
|
+
export interface QueryReference {
|
|
15
|
+
readonly payload: unknown;
|
|
16
|
+
readonly query: string;
|
|
17
|
+
}
|
|
18
|
+
type ReferenceSchema<TQuery extends QueryShape> = TQuery extends QueryShape ? Schema.Struct<{
|
|
19
|
+
query: Schema.Literal<TQuery["name"]>;
|
|
20
|
+
payload: TQuery["payload"];
|
|
21
|
+
}> : never;
|
|
22
|
+
declare const ChangesReads_base: Context.ServiceClass<ChangesReads, "@shivaedev/effect-contract/ChangesReads", (references: readonly QueryReference[]) => readonly Key[]>;
|
|
23
|
+
export declare class ChangesReads extends ChangesReads_base {
|
|
24
|
+
}
|
|
25
|
+
export declare function queryKeys(queries: readonly QueryShape[], requested: readonly QueryReference[]): readonly Key[];
|
|
26
|
+
export declare function changesRpc<const TName extends string, const TQueries extends readonly QueryShape[]>(name: TName, queries: TQueries): Rpc.Rpc<`${TName}.$changes`, Schema.Struct<{
|
|
27
|
+
queries: Schema.$Array<Schema.Union<readonly ReferenceSchema<TQueries[number]>[]>>;
|
|
19
28
|
}>, import("effect/rpc/RpcSchema").Stream<Schema.Union<readonly [Schema.Struct<{
|
|
20
29
|
readonly _tag: Schema.Literal<"Changed">;
|
|
21
30
|
readonly keys: Schema.$Array<Schema.Union<readonly [Schema.Struct<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serverMetadata.d.ts","sourceRoot":"","sources":["../src/serverMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACjC,OAAO,EAAE,GAAG,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"serverMetadata.d.ts","sourceRoot":"","sources":["../src/serverMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACjC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC,OAAO,KAAK,EAAgB,UAAU,EAAE,MAAM,eAAe,CAAC;;AAE9D,qBAAa,UAAW,SAAQ,eAA2F;CAAG;;AAE9H,qBAAa,mBAAoB,SAAQ,wBAExC;CAAG;;AAEJ,qBAAa,QAAS,SAAQ,aAA6E;CAAG;AAE9G,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACvB;AAED,KAAK,eAAe,CAAC,MAAM,SAAS,UAAU,IAAI,MAAM,SAAS,UAAU,GACxE,MAAM,CAAC,MAAM,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,SAAS,CAAC,CAAA;CAAE,CAAC,GACpF,KAAK,CAAC;4HAEoE,SAAS,cAAc,EAAE,KAAK,SAAS,GAAG,EAAE;AAAzH,qBAAa,YAAa,SAAQ,iBAEjC;CAAG;AAEJ,wBAAgB,SAAS,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,EAAE,SAAS,EAAE,SAAS,cAAc,EAAE,GAAG,SAAS,GAAG,EAAE,CAQ9G;AASD,wBAAgB,UAAU,CAAC,KAAK,CAAC,KAAK,SAAS,MAAM,EAAE,KAAK,CAAC,QAAQ,SAAS,SAAS,UAAU,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ;;;;;;;;;;;;;;iDAKlI"}
|
package/dist/serverMetadata.js
CHANGED
|
@@ -1,12 +1,27 @@
|
|
|
1
1
|
import { Context, Schema } from "effect";
|
|
2
2
|
import { Rpc } from "effect/rpc";
|
|
3
|
-
import {
|
|
4
|
-
import { LiveHint } from "./live.js";
|
|
3
|
+
import { LiveHint } from "#live.ts";
|
|
5
4
|
export class QueryReads extends Context.Service()("@shivaedev/effect-contract/QueryReads") {
|
|
6
5
|
}
|
|
7
6
|
export class CommandInvalidation extends Context.Service()("@shivaedev/effect-contract/CommandInvalidation") {
|
|
8
7
|
}
|
|
9
|
-
export
|
|
10
|
-
|
|
8
|
+
export class KeyScope extends Context.Service()("@shivaedev/effect-contract/KeyScope") {
|
|
9
|
+
}
|
|
10
|
+
export class ChangesReads extends Context.Service()("@shivaedev/effect-contract/ChangesReads") {
|
|
11
|
+
}
|
|
12
|
+
export function queryKeys(queries, requested) {
|
|
13
|
+
return requested.flatMap((reference) => {
|
|
14
|
+
const declared = queries.find((candidate) => candidate.name === reference.query);
|
|
15
|
+
if (declared === undefined) {
|
|
16
|
+
throw new Error(`Unknown query: ${reference.query}`);
|
|
17
|
+
}
|
|
18
|
+
return declared.reads(reference.payload);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
function referenceSchemas(queries) {
|
|
22
|
+
return Schema.Array(Schema.Union(queries.map((query) => Schema.Struct({ payload: query.payload, query: Schema.Literal(query.name) }))));
|
|
23
|
+
}
|
|
24
|
+
export function changesRpc(name, queries) {
|
|
25
|
+
return Rpc.make(`${name}.$changes`, { payload: { queries: referenceSchemas(queries) }, stream: true, success: LiveHint }).annotate(ChangesReads, (requested) => queryKeys(queries, requested));
|
|
11
26
|
}
|
|
12
27
|
//# sourceMappingURL=serverMetadata.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serverMetadata.js","sourceRoot":"","sources":["../src/serverMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"serverMetadata.js","sourceRoot":"","sources":["../src/serverMetadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAEjC,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAGpC,MAAM,OAAO,UAAW,SAAQ,OAAO,CAAC,OAAO,EAAmC,CAAC,uCAAuC,CAAC;CAAG;AAE9H,MAAM,OAAO,mBAAoB,SAAQ,OAAO,CAAC,OAAO,EAAoD,CAC3G,gDAAgD,CAChD;CAAG;AAEJ,MAAM,OAAO,QAAS,SAAQ,OAAO,CAAC,OAAO,EAAuB,CAAC,qCAAqC,CAAC;CAAG;AAW9G,MAAM,OAAO,YAAa,SAAQ,OAAO,CAAC,OAAO,EAA2E,CAC3H,yCAAyC,CACzC;CAAG;AAEJ,MAAM,UAAU,SAAS,CAAC,OAA8B,EAAE,SAAoC;IAC7F,OAAO,SAAS,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE;QACtC,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,SAAS,CAAC,KAAK,CAAC,CAAC;QACjF,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,kBAAkB,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC;QACtD,CAAC;QACD,OAAO,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;AACJ,CAAC;AAKD,SAAS,gBAAgB,CAAC,OAA8B;IACvD,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AACzI,CAAC;AAED,MAAM,UAAU,UAAU,CAA2E,IAAW,EAAE,OAAiB;IAClI,OAAO,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,WAAW,EAAE,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,gBAAgB,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,CACjI,YAAY,EACZ,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,CAC5C,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shivaedev/effect-contract",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "Typed query and command contracts over native Effect RPC and reactivity",
|
|
5
5
|
"homepage": "https://github.com/ShivaeDev/platform/tree/main/packages/effect-contract#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -41,24 +41,24 @@
|
|
|
41
41
|
"README.md"
|
|
42
42
|
],
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@shivaedev/types": "0.
|
|
44
|
+
"@shivaedev/types": "0.3.0"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@effect/platform-node": "4.0.
|
|
48
|
-
"@effect/vitest": "4.0.
|
|
49
|
-
"@shivaedev/effect-test": "0.
|
|
50
|
-
"@shivaedev/effect-test-sql": "0.
|
|
51
|
-
"@shivaedev/quality": "0.
|
|
52
|
-
"@shivaedev/test-story": "0.
|
|
47
|
+
"@effect/platform-node": "4.0.5",
|
|
48
|
+
"@effect/vitest": "4.0.5",
|
|
49
|
+
"@shivaedev/effect-test": "0.8.1",
|
|
50
|
+
"@shivaedev/effect-test-sql": "0.9.1",
|
|
51
|
+
"@shivaedev/quality": "0.38.0",
|
|
52
|
+
"@shivaedev/test-story": "0.19.0",
|
|
53
53
|
"@types/node": "24.19.2",
|
|
54
|
-
"effect": "4.0.
|
|
54
|
+
"effect": "4.0.5",
|
|
55
55
|
"esbuild": "0.28.2",
|
|
56
|
-
"happy-dom": "
|
|
56
|
+
"happy-dom": "21.0.3",
|
|
57
57
|
"typescript": "7.0.2",
|
|
58
|
-
"vitest": "5.0.
|
|
58
|
+
"vitest": "5.0.5"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
|
-
"effect": "4.0.
|
|
61
|
+
"effect": "4.0.5"
|
|
62
62
|
},
|
|
63
63
|
"engines": {
|
|
64
64
|
"node": ">=24"
|
package/src/automaticLive.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { type Duration, Effect, Stream, SubscriptionRef } from "effect";
|
|
2
|
-
import
|
|
2
|
+
import * as Atom from "effect/reactivity/Atom";
|
|
3
|
+
import * as AtomRegistry from "effect/reactivity/AtomRegistry";
|
|
3
4
|
import type * as AtomRpc from "effect/reactivity/AtomRpc";
|
|
4
|
-
import
|
|
5
|
-
import { type
|
|
6
|
-
import { type
|
|
7
|
-
import type
|
|
5
|
+
import type { BindingOwner } from "#internal/bindingOwner.ts";
|
|
6
|
+
import { type Key, readKeys } from "#keys.ts";
|
|
7
|
+
import { type LiveStatus, live } from "#live.ts";
|
|
8
|
+
import { type ResumeWindow, resumeSignal } from "#resume.ts";
|
|
9
|
+
import type { changesRpc, QueryReference } from "#serverMetadata.ts";
|
|
8
10
|
|
|
9
11
|
declare const window: ResumeWindow | undefined;
|
|
10
12
|
|
|
@@ -19,30 +21,68 @@ export interface LiveBound {
|
|
|
19
21
|
|
|
20
22
|
export type ChangesClient = AtomRpc.AtomRpcClient<unknown, string, ReturnType<typeof changesRpc>>;
|
|
21
23
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
interface Tracked {
|
|
25
|
+
readonly keys: readonly Key[];
|
|
26
|
+
readonly reference: QueryReference;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function automaticLive(service: ChangesClient, name: string, owner?: BindingOwner) {
|
|
30
|
+
const eager = owner === undefined ? Effect.runSync(SubscriptionRef.make<ReadonlyMap<object, Tracked>>(new Map())) : undefined;
|
|
24
31
|
const known = new Set<string>();
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
const tracked = Atom.keepAlive(Atom.make(() => eager ?? Effect.runSync(SubscriptionRef.make<ReadonlyMap<object, Tracked>>(new Map()))));
|
|
33
|
+
function track(registry: AtomRegistry.AtomRegistry | undefined, reference: QueryReference, keys: readonly Key[]) {
|
|
34
|
+
const fresh =
|
|
35
|
+
eager === undefined
|
|
36
|
+
? keys
|
|
37
|
+
: keys.filter((key) => {
|
|
38
|
+
const id = readKeys([key])[0] ?? "";
|
|
39
|
+
if (known.has(id)) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
known.add(id);
|
|
43
|
+
return true;
|
|
44
|
+
});
|
|
45
|
+
if (fresh.length === 0) {
|
|
46
|
+
return () => undefined;
|
|
47
|
+
}
|
|
48
|
+
const token = {};
|
|
49
|
+
const state = eager ?? registry?.get(tracked);
|
|
50
|
+
if (state === undefined) {
|
|
51
|
+
throw new Error("Session query tracking requires its owning registry");
|
|
52
|
+
}
|
|
53
|
+
Effect.runSync(SubscriptionRef.update(state, (current) => new Map([...current, [token, { keys: fresh, reference }]])));
|
|
54
|
+
if (eager !== undefined) {
|
|
55
|
+
return () => undefined;
|
|
36
56
|
}
|
|
57
|
+
return () =>
|
|
58
|
+
Effect.runSync(
|
|
59
|
+
SubscriptionRef.update(state, (current) => {
|
|
60
|
+
const next = new Map(current);
|
|
61
|
+
next.delete(token);
|
|
62
|
+
return next;
|
|
63
|
+
}),
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
function subscribe(current: ReadonlyMap<object, Tracked>) {
|
|
67
|
+
if (current.size === 0) {
|
|
68
|
+
return Stream.never;
|
|
69
|
+
}
|
|
70
|
+
const queries = [...current.values()].map(({ reference }) => reference);
|
|
71
|
+
return Stream.unwrap(service.use((client) => Effect.succeed(client(`${name}.$changes`, { queries }))));
|
|
37
72
|
}
|
|
38
73
|
const subscription = live(service.runtime, {
|
|
74
|
+
keyContext: owner?.context,
|
|
39
75
|
resume: resumeSignal(typeof window === "undefined" ? {} : { window }),
|
|
40
|
-
resyncKeys: () => Effect.runSync(SubscriptionRef.get(keys)),
|
|
41
|
-
stream:
|
|
42
|
-
|
|
43
|
-
current.length === 0 ? Stream.never : Stream.unwrap(service.use((client) => Effect.succeed(client(`${name}.$changes`, { keys: current })))),
|
|
44
|
-
),
|
|
76
|
+
resyncKeys: (registry) => [...Effect.runSync(SubscriptionRef.get(registry.get(tracked))).values()].flatMap(({ keys }) => keys),
|
|
77
|
+
stream: Stream.unwrap(
|
|
78
|
+
Effect.map(AtomRegistry.AtomRegistry, (registry) => SubscriptionRef.changes(registry.get(tracked)).pipe(Stream.switchMap(subscribe))),
|
|
45
79
|
),
|
|
46
80
|
});
|
|
47
|
-
|
|
81
|
+
const connection = Atom.make((get) => {
|
|
82
|
+
if (owner !== undefined && owner.registry !== get.registry) {
|
|
83
|
+
throw new Error("A session-scoped live connection belongs to its binding registry");
|
|
84
|
+
}
|
|
85
|
+
return get(subscription.connection);
|
|
86
|
+
}).pipe(Atom.setIdleTTL(0));
|
|
87
|
+
return { subscription: { ...subscription, connection }, track };
|
|
48
88
|
}
|