@sigrun/shared 0.4.1 → 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/CHANGELOG.md +9 -1
- package/dist/access.d.ts +60 -0
- package/dist/access.js +87 -0
- package/dist/ambient.d.ts +54 -0
- package/dist/ambient.js +25 -0
- package/dist/blocks/format.d.ts +28 -0
- package/dist/blocks/format.js +199 -0
- package/dist/blocks/icons.d.ts +12 -0
- package/dist/blocks/icons.js +64 -0
- package/dist/blocks/index.d.ts +25 -0
- package/dist/blocks/index.js +21 -0
- package/dist/blocks/instance.d.ts +29 -0
- package/dist/blocks/instance.js +51 -0
- package/dist/blocks/lttb.d.ts +16 -0
- package/dist/blocks/lttb.js +67 -0
- package/dist/blocks/ops.d.ts +44 -0
- package/dist/blocks/ops.js +294 -0
- package/dist/blocks/text.d.ts +43 -0
- package/dist/blocks/text.js +804 -0
- package/dist/blocks/transport.d.ts +81 -0
- package/dist/blocks/transport.js +11 -0
- package/dist/blocks/types.d.ts +558 -0
- package/dist/blocks/types.js +17 -0
- package/dist/commands.d.ts +75 -0
- package/dist/commands.js +25 -0
- package/dist/conversations.d.ts +31 -0
- package/dist/conversations.js +94 -0
- package/dist/interactions.d.ts +65 -0
- package/dist/interactions.js +23 -0
- package/dist/jobs.d.ts +109 -0
- package/dist/jobs.js +19 -0
- package/dist/json.d.ts +20 -0
- package/dist/json.js +13 -0
- package/dist/live.d.ts +71 -0
- package/dist/live.js +82 -0
- package/dist/session-meta.d.ts +130 -0
- package/dist/session-meta.js +13 -0
- package/dist/settings.d.ts +449 -0
- package/dist/settings.js +19 -0
- package/dist/themes.d.ts +49 -0
- package/dist/themes.js +155 -0
- package/dist/turns.d.ts +133 -0
- package/dist/turns.js +247 -0
- package/dist/usernames.d.ts +8 -0
- package/dist/usernames.js +39 -0
- package/dist/view-delta.d.ts +54 -0
- package/dist/view-delta.js +135 -0
- package/dist/views.d.ts +1021 -0
- package/dist/views.js +54 -0
- package/package.json +3 -2
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Delta view frames (core hardening W3, spec §7.3 ruling 11): the SSE view
|
|
3
|
+
* stream's incremental frame shape and its pure diff/fold functions, shared
|
|
4
|
+
* by the server (which diffs) and both clients (which fold).
|
|
5
|
+
*
|
|
6
|
+
* The stream keeps `event: snapshot` (the full wire view) on connect and as
|
|
7
|
+
* the fallback; each later revision is a `event: delta` frame carrying only
|
|
8
|
+
* what changed:
|
|
9
|
+
*
|
|
10
|
+
* - `entries.append` / `entries.remove` — the entry list keyed by `id`;
|
|
11
|
+
* removals plus a pure suffix append are representable, anything else
|
|
12
|
+
* (a head insert, a reorder — e.g. a compaction's new head marker) makes
|
|
13
|
+
* {@link diffViews} return `undefined` and the server sends a fresh
|
|
14
|
+
* snapshot instead;
|
|
15
|
+
* - `docs.set` / `docs.unset` — the changed/removed named documents;
|
|
16
|
+
* - `conversation` / `steer` — present only when they differ.
|
|
17
|
+
*
|
|
18
|
+
* Purity: a shared wire module — `import type` sibling-only (the purity
|
|
19
|
+
* guard in test/views-purity.test.ts); the runtime functions below are
|
|
20
|
+
* dependency-free so both clients (DOM-only webui, NodeNext tui) and the
|
|
21
|
+
* server fold identically.
|
|
22
|
+
*/
|
|
23
|
+
/** Structural equality for the JSON-shaped slots (docs/conversation/steer). */
|
|
24
|
+
function jsonEqual(a, b) {
|
|
25
|
+
return a === b || JSON.stringify(a) === JSON.stringify(b);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Diff two consecutive wire views into a delta, or `undefined` when the
|
|
29
|
+
* change is not representable: entries are keyed by `id`, `remove` is the
|
|
30
|
+
* prev ids absent from next, and AFTER removal prev's remaining ids must be
|
|
31
|
+
* a PREFIX of next's (append-only tail). A head insert or reorder fails the
|
|
32
|
+
* prefix rule → `undefined` → the caller sends a fresh snapshot.
|
|
33
|
+
*/
|
|
34
|
+
export function diffViews(prev, next) {
|
|
35
|
+
const delta = {};
|
|
36
|
+
// Entries: removals, then the prefix rule, then the appended suffix.
|
|
37
|
+
const nextIds = new Set(next.entries.map((entry) => entry.id));
|
|
38
|
+
const remove = prev.entries
|
|
39
|
+
.filter((entry) => !nextIds.has(entry.id))
|
|
40
|
+
.map((entry) => entry.id);
|
|
41
|
+
const remaining = prev.entries.filter((entry) => nextIds.has(entry.id));
|
|
42
|
+
const prefix = remaining.every((entry, index) => entry.id === next.entries[index]?.id);
|
|
43
|
+
if (!prefix)
|
|
44
|
+
return undefined;
|
|
45
|
+
const append = next.entries.slice(remaining.length);
|
|
46
|
+
if (remove.length > 0 || append.length > 0) {
|
|
47
|
+
delta.entries = {};
|
|
48
|
+
if (remove.length > 0)
|
|
49
|
+
delta.entries.remove = remove;
|
|
50
|
+
if (append.length > 0)
|
|
51
|
+
delta.entries.append = [...append];
|
|
52
|
+
}
|
|
53
|
+
// Docs: reference-equal first (the common no-op revision), JSON second.
|
|
54
|
+
const docKeys = new Set([
|
|
55
|
+
...Object.keys(prev.docs),
|
|
56
|
+
...Object.keys(next.docs),
|
|
57
|
+
]);
|
|
58
|
+
const set = {};
|
|
59
|
+
const unset = [];
|
|
60
|
+
for (const key of docKeys) {
|
|
61
|
+
const before = prev.docs[key];
|
|
62
|
+
const after = next.docs[key];
|
|
63
|
+
if (after === undefined) {
|
|
64
|
+
if (before !== undefined)
|
|
65
|
+
unset.push(key);
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
if (before === undefined || !jsonEqual(before, after))
|
|
69
|
+
set[key] = after;
|
|
70
|
+
}
|
|
71
|
+
if (unset.length > 0 || Object.keys(set).length > 0) {
|
|
72
|
+
delta.docs = {};
|
|
73
|
+
if (unset.length > 0)
|
|
74
|
+
delta.docs.unset = unset;
|
|
75
|
+
if (Object.keys(set).length > 0)
|
|
76
|
+
delta.docs.set = set;
|
|
77
|
+
}
|
|
78
|
+
if (!jsonEqual(prev.conversation, next.conversation)) {
|
|
79
|
+
delta.conversation = next.conversation;
|
|
80
|
+
}
|
|
81
|
+
if (!jsonEqual(prev.steer, next.steer)) {
|
|
82
|
+
delta.steer = next.steer;
|
|
83
|
+
}
|
|
84
|
+
return delta;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Fold a delta into a view: filter removed entry ids, concat the appended
|
|
88
|
+
* suffix, shallow-merge docs (set over, unset out), replace
|
|
89
|
+
* `conversation`/`steer` when present. NEVER mutates `view` — every changed
|
|
90
|
+
* slot is a fresh object/array (unchanged slots keep their references).
|
|
91
|
+
*/
|
|
92
|
+
export function applyDelta(view, delta) {
|
|
93
|
+
let entries = view.entries;
|
|
94
|
+
if (delta.entries !== undefined) {
|
|
95
|
+
const removed = new Set(delta.entries.remove ?? []);
|
|
96
|
+
entries = [
|
|
97
|
+
...view.entries.filter((entry) => !removed.has(entry.id)),
|
|
98
|
+
...(delta.entries.append ?? []),
|
|
99
|
+
];
|
|
100
|
+
}
|
|
101
|
+
let docs = view.docs;
|
|
102
|
+
if (delta.docs !== undefined) {
|
|
103
|
+
const unset = new Set(delta.docs.unset ?? []);
|
|
104
|
+
const merged = {};
|
|
105
|
+
for (const [key, value] of Object.entries(view.docs)) {
|
|
106
|
+
if (!unset.has(key))
|
|
107
|
+
merged[key] = value;
|
|
108
|
+
}
|
|
109
|
+
for (const [key, value] of Object.entries(delta.docs.set ?? {})) {
|
|
110
|
+
merged[key] = value;
|
|
111
|
+
}
|
|
112
|
+
docs = merged;
|
|
113
|
+
}
|
|
114
|
+
return {
|
|
115
|
+
...view,
|
|
116
|
+
entries,
|
|
117
|
+
docs,
|
|
118
|
+
conversation: delta.conversation ?? view.conversation,
|
|
119
|
+
steer: delta.steer ?? view.steer,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
/** True when every slot is absent or empty (the server skips these frames). */
|
|
123
|
+
export function isEmptyDelta(delta) {
|
|
124
|
+
const entries = delta.entries;
|
|
125
|
+
if (entries !== undefined &&
|
|
126
|
+
((entries.append?.length ?? 0) > 0 || (entries.remove?.length ?? 0) > 0)) {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
const docs = delta.docs;
|
|
130
|
+
if (docs !== undefined &&
|
|
131
|
+
(Object.keys(docs.set ?? {}).length > 0 || (docs.unset?.length ?? 0) > 0)) {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
return delta.conversation === undefined && delta.steer === undefined;
|
|
135
|
+
}
|