@uicast/core 0.0.1-beta.2 → 0.0.1

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.
Files changed (78) hide show
  1. package/CHANGELOG.md +3 -13
  2. package/README.md +120 -1
  3. package/dist/build-elements-by-key.d.ts +13 -0
  4. package/dist/build-elements-by-key.js +39 -0
  5. package/dist/constants.d.ts +2 -0
  6. package/dist/constants.js +4 -0
  7. package/dist/create-component-definition.d.ts +26 -0
  8. package/dist/create-component-definition.js +74 -0
  9. package/dist/entry-error.d.ts +41 -31
  10. package/dist/entry-error.js +49 -20
  11. package/dist/entry-shape.d.ts +7 -0
  12. package/dist/entry-shape.js +88 -0
  13. package/dist/expr/evaluate.d.ts +4 -6
  14. package/dist/expr/evaluate.js +36 -46
  15. package/dist/expr/extract-deps.d.ts +3 -1
  16. package/dist/expr/extract-deps.js +20 -20
  17. package/dist/expr/plan-step-waves.d.ts +8 -0
  18. package/dist/expr/plan-step-waves.js +45 -0
  19. package/dist/index.d.ts +7 -8
  20. package/dist/index.js +5 -9
  21. package/dist/internal.d.ts +12 -0
  22. package/dist/internal.js +13 -0
  23. package/dist/json-schema.d.ts +58 -0
  24. package/dist/json-schema.js +73 -0
  25. package/dist/prompt/format.d.ts +5 -0
  26. package/dist/prompt/format.js +22 -0
  27. package/dist/prompt/get-common-instructions-partial-prompt.d.ts +20 -10
  28. package/dist/prompt/get-common-instructions-partial-prompt.js +11 -9
  29. package/dist/prompt/get-components-partial-prompt.d.ts +20 -28
  30. package/dist/prompt/get-components-partial-prompt.js +122 -123
  31. package/dist/prompt/get-edit-request-prompt.d.ts +16 -16
  32. package/dist/prompt/get-edit-request-prompt.js +11 -18
  33. package/dist/prompt/get-error-recovery-prompt.d.ts +25 -14
  34. package/dist/prompt/get-error-recovery-prompt.js +17 -14
  35. package/dist/prompt/get-expressions-partial-prompt.d.ts +19 -20
  36. package/dist/prompt/get-expressions-partial-prompt.js +11 -21
  37. package/dist/prompt/get-functions-partial-prompt.d.ts +16 -16
  38. package/dist/prompt/get-functions-partial-prompt.js +52 -40
  39. package/dist/prompt/get-scope-partial-prompt.d.ts +17 -17
  40. package/dist/prompt/get-scope-partial-prompt.js +21 -29
  41. package/dist/prompt/index.js +0 -2
  42. package/dist/prompt/json-schema-to-ts.d.ts +6 -0
  43. package/dist/prompt/json-schema-to-ts.js +146 -0
  44. package/dist/prompt/md/EXPRESSIONS.json +1 -1
  45. package/dist/prompt/md/INSTRUCTIONS.json +1 -1
  46. package/dist/prompt/shared-types.d.ts +5 -0
  47. package/dist/prompt/shared-types.js +82 -0
  48. package/dist/scope/create-proxy-scope.d.ts +52 -17
  49. package/dist/scope/create-proxy-scope.js +280 -86
  50. package/dist/scope/parse-scope.d.ts +2 -20
  51. package/dist/scope/parse-scope.js +10 -35
  52. package/dist/scope/parse-set-address.d.ts +16 -0
  53. package/dist/scope/parse-set-address.js +52 -0
  54. package/dist/stream-json-lines.d.ts +14 -0
  55. package/dist/stream-json-lines.js +59 -0
  56. package/dist/types.d.ts +81 -46
  57. package/dist/types.js +6 -9
  58. package/dist/url-policy.d.ts +45 -0
  59. package/dist/url-policy.js +252 -0
  60. package/package.json +18 -16
  61. package/dist/def/create-component-definition.d.ts +0 -9
  62. package/dist/def/create-component-definition.js +0 -10
  63. package/dist/expr/analyze.d.ts +0 -5
  64. package/dist/expr/analyze.js +0 -189
  65. package/dist/expr/ast-utils.d.ts +0 -4
  66. package/dist/expr/ast-utils.js +0 -23
  67. package/dist/expr/globals.d.ts +0 -3
  68. package/dist/expr/globals.js +0 -111
  69. package/dist/expr/safer-eval.d.ts +0 -21
  70. package/dist/expr/safer-eval.js +0 -170
  71. package/dist/expr/validate.d.ts +0 -7
  72. package/dist/expr/validate.js +0 -109
  73. package/dist/prompt-utils/json-schema-to-ts.d.ts +0 -73
  74. package/dist/prompt-utils/json-schema-to-ts.js +0 -199
  75. package/dist/stream/stream-json-lines.d.ts +0 -1
  76. package/dist/stream/stream-json-lines.js +0 -94
  77. package/dist/utils/utils.d.ts +0 -13
  78. package/dist/utils/utils.js +0 -58
@@ -1,73 +0,0 @@
1
- type JSONSchemaType = "object" | "array" | "string" | "number" | "boolean" | "null" | "integer";
2
- /**
3
- * JSON Schema shape this module reads — a recursive structural type covering
4
- * the draft-07 / 2020-12 keywords a Standard-Schema `toJSONSchema()` can emit
5
- * (primitives, composition, objects, arrays/tuples, `$ref` + `$defs`, and the
6
- * refinement keywords that constrain a value without changing its TypeScript
7
- * type). Every sub-schema slot is another `JSONSchema`.
8
- *
9
- * `JSONSchemaToTs` still takes `unknown` and narrows at runtime, because a
10
- * schema value can also be a boolean (`true`/`false`) — and, in legacy
11
- * draft-07, an `items` array — which this object type intentionally doesn't
12
- * model. The function reads back through itself, so the recursion stays loose.
13
- */
14
- export interface JSONSchema {
15
- $schema?: "https://json-schema.org/draft/2020-12/schema" | "http://json-schema.org/draft-07/schema#";
16
- type?: JSONSchemaType | JSONSchemaType[];
17
- format?: string;
18
- pattern?: string;
19
- $ref?: string;
20
- items?: boolean | JSONSchema;
21
- prefixItems?: JSONSchema[];
22
- additionalItems?: boolean | JSONSchema;
23
- enum?: unknown[];
24
- minimum?: number;
25
- maximum?: number;
26
- exclusiveMinimum?: number;
27
- exclusiveMaximum?: number;
28
- minItems?: number;
29
- maxItems?: number;
30
- title?: string;
31
- description?: string;
32
- properties?: {
33
- [key: string]: JSONSchema;
34
- };
35
- required?: string[];
36
- examples?: unknown[];
37
- not?: JSONSchema;
38
- $defs?: {
39
- [key: string]: JSONSchema;
40
- };
41
- definitions?: {
42
- [key: string]: JSONSchema;
43
- };
44
- additionalProperties?: boolean | JSONSchema;
45
- anyOf?: JSONSchema[];
46
- oneOf?: JSONSchema[];
47
- allOf?: JSONSchema[];
48
- const?: unknown;
49
- example?: unknown;
50
- contentEncoding?: string;
51
- contentMediaType?: string;
52
- minLength?: number;
53
- maxLength?: number;
54
- "x-tsType"?: string;
55
- }
56
- export type JSONSchemaToTsOptions = {
57
- /**
58
- * Render objects one property per line, indented. The string is the prefix
59
- * every generated line starts with (the caller's continuation indent, e.g.
60
- * `" "` inside a Markdown bullet); nesting adds two spaces per level.
61
- * Omit for the compact single-line form.
62
- */
63
- multiline?: string;
64
- };
65
- /**
66
- * Convert a JSON Schema to a compact TypeScript type string for the prompt.
67
- *
68
- * Pass the whole schema document (with any `$defs` / `definitions`): local
69
- * `$ref`s resolve against it, and a recursive schema terminates — the cycle's
70
- * back-edge renders as `unknown` while everything above it stays fully typed.
71
- */
72
- export declare function JSONSchemaToTs(jsonSchema: unknown, options?: JSONSchemaToTsOptions): string;
73
- export {};
@@ -1,199 +0,0 @@
1
- /**
2
- * Convert a JSON Schema to a compact TypeScript type string for the prompt.
3
- *
4
- * Pass the whole schema document (with any `$defs` / `definitions`): local
5
- * `$ref`s resolve against it, and a recursive schema terminates — the cycle's
6
- * back-edge renders as `unknown` while everything above it stays fully typed.
7
- */
8
- export function JSONSchemaToTs(jsonSchema, options) {
9
- const ml = (options === null || options === void 0 ? void 0 : options.multiline) !== undefined
10
- ? { pad: options.multiline, depth: 0 }
11
- : null;
12
- return toTs(jsonSchema, jsonSchema, new Set(), ml);
13
- }
14
- /**
15
- * Recursive worker. Renders the node's type, then — when the node carries a
16
- * `description` — appends it as a trailing ` /* … *​/` comment, so per-field
17
- * docs (Zod `.describe()` / `.meta({ description })`) survive into the prompt
18
- * at every nesting level. Nodes without a description add nothing.
19
- */
20
- function toTs(jsonSchema, root, seen, ml = null) {
21
- var _a;
22
- const base = toTsBase(jsonSchema, root, seen, ml);
23
- if (jsonSchema !== null &&
24
- typeof jsonSchema === "object" &&
25
- typeof jsonSchema.description === "string") {
26
- // One line, and never a premature close: `*/` inside a description
27
- // would truncate the comment (and the type after it).
28
- const description = (_a = jsonSchema.description) === null || _a === void 0 ? void 0 : _a.replace(/\s+/g, " ").replace(/\*\//g, "*").trim();
29
- if (description)
30
- return `${base} /* ${description} */`;
31
- }
32
- return base;
33
- }
34
- /**
35
- * Type rendering without the description pass. `root` is the document the
36
- * first call was handed (the resolution base for `$ref`); `seen` is the set of
37
- * refs currently being expanded on this path, so a cycle short-circuits to
38
- * `unknown` instead of recursing forever.
39
- */
40
- function toTsBase(jsonSchema, root, seen, ml) {
41
- if (jsonSchema === true)
42
- return "unknown";
43
- if (jsonSchema === false)
44
- return "never";
45
- if (jsonSchema === null || jsonSchema === undefined)
46
- return "unknown";
47
- if (typeof jsonSchema !== "object")
48
- return "unknown";
49
- const schema = jsonSchema;
50
- if (typeof schema.$ref === "string") {
51
- if (seen.has(schema.$ref))
52
- return "unknown"; // cycle back-edge
53
- const target = resolveRef(schema.$ref, root);
54
- if (target === undefined)
55
- return "unknown";
56
- seen.add(schema.$ref);
57
- // When the referencing node has its own description, it wins (it names
58
- // the field's role at THIS use site) — render the target without its
59
- // root annotation so the field isn't double-commented. The target's
60
- // nested fields keep their own annotations either way.
61
- const resolved = typeof schema.description === "string"
62
- ? toTsBase(target, root, seen, ml)
63
- : toTs(target, root, seen, ml);
64
- seen.delete(schema.$ref);
65
- return resolved;
66
- }
67
- if ("const" in schema)
68
- return JSON.stringify(schema.const);
69
- if (schema.enum) {
70
- return schema.enum.map((v) => JSON.stringify(v)).join(" | ") || "never";
71
- }
72
- if (schema.allOf) {
73
- const parts = schema.allOf.map((s) => toTs(s, root, seen, ml));
74
- return parts.length ? `(${parts.join(" & ")})` : "unknown";
75
- }
76
- if (schema.anyOf) {
77
- const parts = schema.anyOf.map((s) => toTs(s, root, seen, ml));
78
- return parts.length ? `(${parts.join(" | ")})` : "never";
79
- }
80
- if (schema.oneOf) {
81
- const parts = schema.oneOf.map((s) => toTs(s, root, seen, ml));
82
- return parts.length ? `(${parts.join(" | ")})` : "never";
83
- }
84
- if (schema.not)
85
- return "unknown";
86
- if (Array.isArray(schema.type)) {
87
- // Drop the description on the per-type variants — the wrapper already
88
- // annotates the union as a whole; keeping it would stamp every member.
89
- const types = schema.type.map((t) => toTs(Object.assign(Object.assign({}, schema), { type: t, description: undefined }), root, seen, ml));
90
- return types.length ? `(${types.join(" | ")})` : "unknown";
91
- }
92
- const type = schema.type;
93
- if (type === "string")
94
- return "string";
95
- if (type === "number" || type === "integer")
96
- return "number";
97
- if (type === "boolean")
98
- return "boolean";
99
- if (type === "null")
100
- return "null";
101
- if (type === "object" ||
102
- schema.properties ||
103
- schema.additionalProperties !== undefined) {
104
- const props = schema.properties || {};
105
- const required = schema.required || [];
106
- const childMl = ml ? { pad: ml.pad, depth: ml.depth + 1 } : null;
107
- const propStrings = Object.entries(props).map(([key, value]) => {
108
- const isRequired = required.includes(key);
109
- const safeName = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key)
110
- ? key
111
- : JSON.stringify(key);
112
- return `${safeName}${isRequired ? "" : "?"}: ${toTs(value, root, seen, childMl)}`;
113
- });
114
- let additionalType = null;
115
- if (schema.additionalProperties === true) {
116
- additionalType = "unknown";
117
- }
118
- else if (schema.additionalProperties &&
119
- typeof schema.additionalProperties === "object") {
120
- additionalType = toTs(schema.additionalProperties, root, seen);
121
- }
122
- if (propStrings.length === 0 && additionalType) {
123
- return `{ [key: string]: ${additionalType} }`;
124
- }
125
- if (propStrings.length === 0 && !additionalType) {
126
- return schema.additionalProperties === false
127
- ? "{}"
128
- : "{ [key: string]: unknown }";
129
- }
130
- let result;
131
- if (ml) {
132
- // One property per line: fields one level deeper than this object's
133
- // braces, the closing brace back at the object's own level.
134
- const inner = ml.pad + " ".repeat(ml.depth + 1);
135
- const closing = ml.pad + " ".repeat(ml.depth);
136
- result = `{\n${inner}${propStrings.join(`;\n${inner}`)};\n${closing}}`;
137
- }
138
- else {
139
- result = `{ ${propStrings.join("; ")} }`;
140
- }
141
- if (additionalType) {
142
- result = `(${result} & { [key: string]: ${additionalType} })`;
143
- }
144
- return result;
145
- }
146
- if (type === "array" || schema.items || schema.prefixItems) {
147
- if (schema.prefixItems) {
148
- const tupleTypes = schema.prefixItems.map((s) => toTs(s, root, seen));
149
- if (schema.items === false)
150
- return `[${tupleTypes.join(", ")}]`;
151
- const restType = schema.items ? toTs(schema.items, root, seen) : "unknown";
152
- return `[${tupleTypes.join(", ")}, ...${restType}[]]`;
153
- }
154
- if (schema.items !== undefined && schema.items !== null) {
155
- if (Array.isArray(schema.items)) {
156
- const tupleTypes = schema.items.map((s) => toTs(s, root, seen));
157
- if (schema.additionalItems === false) {
158
- return `[${tupleTypes.join(", ")}]`;
159
- }
160
- const restType = schema.additionalItems
161
- ? toTs(schema.additionalItems, root, seen)
162
- : "unknown";
163
- return `[${tupleTypes.join(", ")}, ...${restType}[]]`;
164
- }
165
- const itemTs = toTs(schema.items, root, seen, ml);
166
- // An item type ENDING in an annotation must be parenthesized —
167
- // `string /* x */[]` reads as if the comment interrupts the type;
168
- // `(string /* x */)[]` keeps the array suffix unambiguous. A comment
169
- // safely inside braces (`{ a: string /* x */ }[]`) needs nothing.
170
- return itemTs.endsWith("*/") ? `(${itemTs})[]` : `${itemTs}[]`;
171
- }
172
- return "unknown[]";
173
- }
174
- if (schema.properties) {
175
- return toTs(Object.assign(Object.assign({}, schema), { type: "object" }), root, seen);
176
- }
177
- return "unknown";
178
- }
179
- /**
180
- * Resolve a local JSON Pointer ref (`#/$defs/Foo`, `#/definitions/Bar`)
181
- * against the document root. Returns the target sub-schema, or `undefined`
182
- * for a non-local ref (`https://…`, bare `#`) or a path that doesn't exist —
183
- * the caller renders those as `unknown`.
184
- */
185
- function resolveRef(ref, root) {
186
- if (!ref.startsWith("#/"))
187
- return undefined;
188
- const segments = ref
189
- .slice(2)
190
- .split("/")
191
- .map((seg) => seg.replace(/~1/g, "/").replace(/~0/g, "~"));
192
- let node = root;
193
- for (const seg of segments) {
194
- if (node === null || typeof node !== "object")
195
- return undefined;
196
- node = node[seg];
197
- }
198
- return node;
199
- }
@@ -1 +0,0 @@
1
- export declare function streamJsonLines<T = unknown>(source: ReadableStream<Uint8Array | string> | AsyncIterable<string | Uint8Array>): AsyncGenerator<T>;
@@ -1,94 +0,0 @@
1
- var __asyncValues = (this && this.__asyncValues) || function (o) {
2
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
3
- var m = o[Symbol.asyncIterator], i;
4
- return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
5
- function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
6
- function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
7
- };
8
- var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
9
- var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
10
- var i, p;
11
- return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
12
- function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }
13
- };
14
- var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
15
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
16
- var g = generator.apply(thisArg, _arguments || []), i, q = [];
17
- return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;
18
- function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }
19
- function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }
20
- function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
21
- function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
22
- function fulfill(value) { resume("next", value); }
23
- function reject(value) { resume("throw", value); }
24
- function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
25
- };
26
- // Yields every parseable JSON value from a byte or string stream, skipping
27
- // blank/non-JSON lines (code fences, model prose, partial lines). Narrow the
28
- // element type via <T>; shape-checking is the caller's concern.
29
- export function streamJsonLines(source) {
30
- return __asyncGenerator(this, arguments, function* streamJsonLines_1() {
31
- var _a, e_1, _b, _c;
32
- const decoder = new TextDecoder();
33
- let buffer = "";
34
- try {
35
- for (var _d = true, _e = __asyncValues(toAsyncIterable(source)), _f; _f = yield __await(_e.next()), _a = _f.done, !_a; _d = true) {
36
- _c = _f.value;
37
- _d = false;
38
- const chunk = _c;
39
- buffer += typeof chunk === "string" ? chunk : decoder.decode(chunk, { stream: true });
40
- let nl = buffer.indexOf("\n");
41
- while (nl !== -1) {
42
- yield __await(yield* __asyncDelegator(__asyncValues(parseLine(buffer.slice(0, nl)))));
43
- buffer = buffer.slice(nl + 1);
44
- nl = buffer.indexOf("\n");
45
- }
46
- }
47
- }
48
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
49
- finally {
50
- try {
51
- if (!_d && !_a && (_b = _e.return)) yield __await(_b.call(_e));
52
- }
53
- finally { if (e_1) throw e_1.error; }
54
- }
55
- yield __await(yield* __asyncDelegator(__asyncValues(parseLine(buffer + decoder.decode()))));
56
- });
57
- }
58
- function* parseLine(raw) {
59
- const line = raw.trim();
60
- if (!line)
61
- return;
62
- try {
63
- yield JSON.parse(line);
64
- }
65
- catch (_a) {
66
- // non-JSON noise (fences, prose, partial) — drop it
67
- }
68
- }
69
- function toAsyncIterable(source) {
70
- if (Symbol.asyncIterator in source) {
71
- return source;
72
- }
73
- // Browser ReadableStream isn't async-iterable — pull it through a reader.
74
- const stream = source;
75
- return {
76
- [Symbol.asyncIterator]() {
77
- return __asyncGenerator(this, arguments, function* _a() {
78
- const reader = stream.getReader();
79
- try {
80
- for (;;) {
81
- const { done, value } = yield __await(reader.read());
82
- if (done)
83
- return yield __await(void 0);
84
- if (value !== undefined)
85
- yield yield __await(value);
86
- }
87
- }
88
- finally {
89
- reader.releaseLock();
90
- }
91
- });
92
- },
93
- };
94
- }
@@ -1,13 +0,0 @@
1
- import type { ComponentEntry } from "../types.js";
2
- /**
3
- * Build an elements-by-key map from the NDJSON lines array.
4
- *
5
- * When an entry with a duplicate key is encountered (i.e. the LLM re-emits a
6
- * entry to correct a mistake), the old subtree is removed before inserting
7
- * the replacement — except old nodes the new `children` array still
8
- * references (directly or through a kept child), which survive with their
9
- * own subtrees. This lets the LLM restructure a parent by re-emitting just
10
- * that entry, keeping existing children by reference, without regenerating
11
- * the entire tree.
12
- */
13
- export declare function buildElementsById(lines: ComponentEntry[]): Record<string, ComponentEntry>;
@@ -1,58 +0,0 @@
1
- /**
2
- * Collect all descendant IDs of a given entry (not including the entry itself)
3
- * by walking its children array recursively.
4
- */
5
- function collectDescendantIds(id, map) {
6
- const result = new Set();
7
- const stack = [id];
8
- while (stack.length > 0) {
9
- const current = stack.pop();
10
- const entry = map[current];
11
- if (entry === null || entry === void 0 ? void 0 : entry.children) {
12
- for (const childId of entry.children) {
13
- if (!result.has(childId)) {
14
- result.add(childId);
15
- stack.push(childId);
16
- }
17
- }
18
- }
19
- }
20
- return result;
21
- }
22
- /**
23
- * Build an elements-by-key map from the NDJSON lines array.
24
- *
25
- * When an entry with a duplicate key is encountered (i.e. the LLM re-emits a
26
- * entry to correct a mistake), the old subtree is removed before inserting
27
- * the replacement — except old nodes the new `children` array still
28
- * references (directly or through a kept child), which survive with their
29
- * own subtrees. This lets the LLM restructure a parent by re-emitting just
30
- * that entry, keeping existing children by reference, without regenerating
31
- * the entire tree.
32
- */
33
- export function buildElementsById(lines) {
34
- var _a;
35
- const map = {};
36
- for (const line of lines) {
37
- if (map[line.key]) {
38
- const oldDescendants = collectDescendantIds(line.key, map);
39
- const kept = new Set();
40
- const stack = [...((_a = line.children) !== null && _a !== void 0 ? _a : [])];
41
- while (stack.length > 0) {
42
- const id = stack.pop();
43
- if (kept.has(id) || !oldDescendants.has(id))
44
- continue;
45
- kept.add(id);
46
- const entry = map[id];
47
- if (entry === null || entry === void 0 ? void 0 : entry.children)
48
- stack.push(...entry.children);
49
- }
50
- for (const descId of oldDescendants) {
51
- if (!kept.has(descId))
52
- delete map[descId];
53
- }
54
- }
55
- map[line.key] = line;
56
- }
57
- return map;
58
- }