@turingfocus/chat-runtime 0.1.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.
@@ -0,0 +1,130 @@
1
+ import { compareTimelineItems, getTimelineItemKey, } from "@turingfocus/chat-protocol";
2
+ import { cloneImmutable, deepEqual } from "./immutable.js";
3
+ const MAX_INDEX_OVERLAY_SIZE = 64;
4
+ const buildIndex = (items) => ({
5
+ base: new Map(items.map((item) => [getTimelineItemKey(item), item])),
6
+ overlay: new Map(),
7
+ });
8
+ const findIndexedItem = (index, key) => index.overlay.get(key) ?? index.base.get(key);
9
+ const advanceIndex = (index, key, item, items) => {
10
+ const overlay = new Map(index.overlay);
11
+ overlay.set(key, item);
12
+ return overlay.size < MAX_INDEX_OVERLAY_SIZE
13
+ ? { base: index.base, overlay }
14
+ : buildIndex(items);
15
+ };
16
+ const freezeItems = (items) => Object.freeze(items);
17
+ const createFromImmutableItems = (candidates) => {
18
+ const byKey = new Map();
19
+ for (const item of candidates)
20
+ byKey.set(getTimelineItemKey(item), item);
21
+ const items = freezeItems([...byKey.values()].sort(compareTimelineItems));
22
+ return { items, index: buildIndex(items) };
23
+ };
24
+ export const createTimelineState = (items) => createFromImmutableItems(items.map((item) => cloneImmutable(item)));
25
+ export const findEventTimelineItem = (state, eventId) => {
26
+ return findIndexedItem(state.index, `event:${eventId}`);
27
+ };
28
+ const findLowerBound = (items, item) => {
29
+ let lower = 0;
30
+ let upper = items.length;
31
+ while (lower < upper) {
32
+ const middle = Math.floor((lower + upper) / 2);
33
+ const current = items[middle];
34
+ if (compareTimelineItems(current, item) < 0)
35
+ lower = middle + 1;
36
+ else
37
+ upper = middle;
38
+ }
39
+ return lower;
40
+ };
41
+ const findCurrentIndex = (items, item) => {
42
+ const index = findLowerBound(items, item);
43
+ const candidate = items[index];
44
+ return candidate !== undefined &&
45
+ getTimelineItemKey(candidate) === getTimelineItemKey(item)
46
+ ? index
47
+ : -1;
48
+ };
49
+ export const upsertTimelineItem = (state, candidate) => {
50
+ const item = cloneImmutable(candidate);
51
+ const key = getTimelineItemKey(item);
52
+ const current = findIndexedItem(state.index, key);
53
+ if (current !== undefined) {
54
+ if (deepEqual(current, item))
55
+ return state;
56
+ const currentIndex = findCurrentIndex(state.items, current);
57
+ if (currentIndex < 0) {
58
+ throw new Error(`Timeline index is inconsistent for ${key}`);
59
+ }
60
+ if (compareTimelineItems(current, item) === 0) {
61
+ const items = [...state.items];
62
+ items[currentIndex] = item;
63
+ const frozenItems = freezeItems(items);
64
+ return {
65
+ items: frozenItems,
66
+ index: advanceIndex(state.index, key, item, frozenItems),
67
+ };
68
+ }
69
+ const withoutCurrent = [...state.items];
70
+ withoutCurrent.splice(currentIndex, 1);
71
+ const insertionIndex = findLowerBound(withoutCurrent, item);
72
+ withoutCurrent.splice(insertionIndex, 0, item);
73
+ const items = freezeItems(withoutCurrent);
74
+ return { items, index: advanceIndex(state.index, key, item, items) };
75
+ }
76
+ const insertionIndex = findLowerBound(state.items, item);
77
+ const items = [...state.items];
78
+ items.splice(insertionIndex, 0, item);
79
+ const frozenItems = freezeItems(items);
80
+ return {
81
+ items: frozenItems,
82
+ index: advanceIndex(state.index, key, item, frozenItems),
83
+ };
84
+ };
85
+ /** Merge an older history page while preserving newer in-memory items. */
86
+ export const mergeHistoryTimeline = (current, history) => {
87
+ const byKey = new Map();
88
+ for (const item of history) {
89
+ const immutable = cloneImmutable(item);
90
+ byKey.set(getTimelineItemKey(immutable), immutable);
91
+ }
92
+ for (const item of current.items) {
93
+ byKey.set(getTimelineItemKey(item), item);
94
+ }
95
+ const merged = createFromImmutableItems([...byKey.values()]);
96
+ return deepEqual(merged.items, current.items) ? current : merged;
97
+ };
98
+ /**
99
+ * Rebase a freshly loaded timeline onto changes published since the load began.
100
+ * Current changes win per stable item key; otherwise the loaded value (including
101
+ * a deletion) is adopted.
102
+ */
103
+ export const rebaseTimelineState = (baseline, loaded, current) => {
104
+ const baselineByKey = new Map(baseline.items.map((item) => [getTimelineItemKey(item), item]));
105
+ const loadedByKey = new Map(loaded.items.map((item) => [getTimelineItemKey(item), item]));
106
+ const currentByKey = new Map(current.items.map((item) => [getTimelineItemKey(item), item]));
107
+ const keys = new Set([
108
+ ...baselineByKey.keys(),
109
+ ...loadedByKey.keys(),
110
+ ...currentByKey.keys(),
111
+ ]);
112
+ const rebasedItems = [];
113
+ for (const key of keys) {
114
+ const baselineItem = baselineByKey.get(key);
115
+ const loadedItem = loadedByKey.get(key);
116
+ const currentItem = currentByKey.get(key);
117
+ const selected = deepEqual(currentItem, baselineItem)
118
+ ? loadedItem
119
+ : currentItem;
120
+ if (selected !== undefined)
121
+ rebasedItems.push(selected);
122
+ }
123
+ const rebased = createFromImmutableItems(rebasedItems);
124
+ if (deepEqual(rebased.items, current.items))
125
+ return current;
126
+ if (deepEqual(rebased.items, loaded.items))
127
+ return loaded;
128
+ return rebased;
129
+ };
130
+ //# sourceMappingURL=timeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeline.js","sourceRoot":"","sources":["../src/timeline.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@turingfocus/chat-runtime",
3
+ "version": "0.1.0",
4
+ "description": "Headless, instance-scoped chat runtime",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/A2C-SMCP/tf-chat-kit.git",
9
+ "directory": "packages/chat-runtime"
10
+ },
11
+ "homepage": "https://github.com/A2C-SMCP/tf-chat-kit#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/A2C-SMCP/tf-chat-kit/issues"
14
+ },
15
+ "type": "module",
16
+ "sideEffects": false,
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "main": "./dist/index.js",
21
+ "module": "./dist/index.js",
22
+ "types": "./dist/index.d.ts",
23
+ "exports": {
24
+ ".": {
25
+ "types": "./dist/index.d.ts",
26
+ "import": "./dist/index.js",
27
+ "default": "./dist/index.js"
28
+ }
29
+ },
30
+ "dependencies": {
31
+ "@turingfocus/chat-protocol": "^0.1.0"
32
+ },
33
+ "publishConfig": {
34
+ "access": "public",
35
+ "registry": "https://registry.npmjs.org/"
36
+ }
37
+ }