@wildwinter/toolkit 0.2.0 → 0.2.2
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 +20 -0
- package/conformance/extensions/manifest.json +1023 -158
- package/conformance/extensions/merge.json +46 -1
- package/conformance/extensions/values.json +736 -91
- package/dist/extensions.cjs +88 -3
- package/dist/extensions.cjs.map +1 -1
- package/dist/extensions.d.cts +36 -1
- package/dist/extensions.d.ts +36 -1
- package/dist/extensions.js +86 -4
- package/dist/extensions.js.map +1 -1
- package/extensions.md +10 -2
- package/package.json +1 -1
package/dist/extensions.d.cts
CHANGED
|
@@ -150,6 +150,17 @@ declare function resolvedClaims(manifest: Manifest, host: HostName, chosen?: Rea
|
|
|
150
150
|
declare function claimClashes(claims: readonly ResolvedClaim[]): Problem[];
|
|
151
151
|
/** One manifest's declarations for one host and node kind, or undefined. */
|
|
152
152
|
declare function targetOf(manifest: Manifest | undefined, host: HostName, kind: string): TargetDecl | undefined;
|
|
153
|
+
/**
|
|
154
|
+
* A claim as a host draws and checks its field: the claim's label, help, value help and constraints, over the
|
|
155
|
+
* host's own declaration for what the claim leaves out (an enum's or flags' values, a quality's stages, the
|
|
156
|
+
* default). The host's vocabulary stands when the claim names none, as the host's ladder always does.
|
|
157
|
+
*/
|
|
158
|
+
declare function effectiveClaim<C extends ClaimDecl>(claim: C, hostDecl: {
|
|
159
|
+
readonly type?: string;
|
|
160
|
+
readonly values?: readonly string[];
|
|
161
|
+
readonly stages?: readonly string[];
|
|
162
|
+
readonly default?: unknown;
|
|
163
|
+
}): C;
|
|
153
164
|
|
|
154
165
|
/** What the host knows about its nodes, for references. */
|
|
155
166
|
interface ValueContext {
|
|
@@ -198,6 +209,8 @@ declare function renameStages(target: TargetDecl, entry: Readonly<Record<string,
|
|
|
198
209
|
* sorted by key, or in the authored order with `order: "preserve"`
|
|
199
210
|
* object(fields) named keys by their own strategy, every other key by `other`
|
|
200
211
|
* (atomic when absent)
|
|
212
|
+
* comments a list of comment threads, merged message by message
|
|
213
|
+
* (`mergeComments`)
|
|
201
214
|
*/
|
|
202
215
|
type Strategy = {
|
|
203
216
|
readonly kind: "atomic";
|
|
@@ -216,9 +229,12 @@ type Strategy = {
|
|
|
216
229
|
readonly kind: "object";
|
|
217
230
|
readonly fields: Readonly<Record<string, Strategy>>;
|
|
218
231
|
readonly other?: Strategy;
|
|
232
|
+
} | {
|
|
233
|
+
readonly kind: "comments";
|
|
219
234
|
};
|
|
220
235
|
declare const ATOMIC: Strategy;
|
|
221
236
|
declare const SET: Strategy;
|
|
237
|
+
declare const COMMENTS: Strategy;
|
|
222
238
|
declare const mapOf: (of: Strategy) => Strategy;
|
|
223
239
|
declare const keyedBy: (key: string, of: Strategy, opts?: {
|
|
224
240
|
order?: "sorted" | "preserve";
|
|
@@ -256,6 +272,25 @@ interface TreeMergeOptions {
|
|
|
256
272
|
declare function stableStringify(value: unknown): string;
|
|
257
273
|
/** Three-way merge `base`, `ours` and `theirs` by `strategy`. A clash keeps ours. */
|
|
258
274
|
declare function mergeTree(strategy: Strategy, base: unknown, ours: unknown, theirs: unknown, opts?: TreeMergeOptions): TreeMergeResult;
|
|
275
|
+
/**
|
|
276
|
+
* Three-way merge two lists of comment threads, the shape both families'
|
|
277
|
+
* comments share: `{ id, messages: [{ author, ts, body, deleted? }], resolved?,
|
|
278
|
+
* ...}`. Lifted from Patter's merge (patterkit design/family-parity-2026-10.md
|
|
279
|
+
* item 5), where a thread merged whole made two replies to one thread clash.
|
|
280
|
+
*
|
|
281
|
+
* - Messages are keyed by author and timestamp, and are the union of both
|
|
282
|
+
* sides', oldest first. A withdrawn message (a tombstone: body emptied,
|
|
283
|
+
* `deleted` set) stays withdrawn whichever side withdrew it, and a message a
|
|
284
|
+
* side removed outright, or lost with its whole thread, counts as withdrawn
|
|
285
|
+
* by that side. One message edited two ways is a clash that keeps ours.
|
|
286
|
+
* - A thread's other fields (its anchor, its marker, `resolved`) merge one by
|
|
287
|
+
* one, a field changed two ways being a clash; a thread one side removed
|
|
288
|
+
* takes the other side's.
|
|
289
|
+
* - A thread with nothing readable left goes, as the editors drop it.
|
|
290
|
+
*
|
|
291
|
+
* Threads come back oldest first, by their first message, then by id.
|
|
292
|
+
*/
|
|
293
|
+
declare function mergeComments(base: unknown, ours: unknown, theirs: unknown, opts?: TreeMergeOptions): TreeMergeResult;
|
|
259
294
|
/** How a value of this type merges (the README's table). */
|
|
260
295
|
declare function strategyForType(decl: TypeDecl): Strategy;
|
|
261
296
|
/** How one node's entry merges: field by field, each by its type. */
|
|
@@ -310,4 +345,4 @@ declare const atKey: (base: string, key: string) => string;
|
|
|
310
345
|
/** `base` and then list position `i`. */
|
|
311
346
|
declare const atIndex: (base: string, i: number) => string;
|
|
312
347
|
|
|
313
|
-
export { ATOMIC, type ClaimDecl, type Conflict, type ConflictKind, type DataMergeResult, type ExtensionData, type FieldDecl, HOSTS, type HostName, type HostSpec, type JsonValue, MANIFEST_FILE_SUFFIX, MANIFEST_SCHEMA, type Manifest, type MergeWarning, type Problem, type ResolvedClaim, SCALAR_TYPES, SET, type ScalarType, type SettingDecl, type StageRename, type Strategy, type TargetDecl, type TreeMergeOptions, type TreeMergeResult, type TypeDecl, UNRESOLVED_KEY, type UnresolvedEntry, VALUE_TYPES, type ValueContext, type ValueType, atIndex, atKey, claimClashes, compileEntry, compiledTarget, defaultOf, entryProblems, extensionDataStrategy, keyedBy, manifestProblems, mapOf, markUnresolved, mergeExtensionData, mergeTree, objectOf, orphanedEntries, parseManifest, renameStages, resolvedClaims, settingValues, stableStringify, strategyForTarget, strategyForType, targetOf, unresolvedOf, unresolvedProblems, valueProblems, withoutMark };
|
|
348
|
+
export { ATOMIC, COMMENTS, type ClaimDecl, type Conflict, type ConflictKind, type DataMergeResult, type ExtensionData, type FieldDecl, HOSTS, type HostName, type HostSpec, type JsonValue, MANIFEST_FILE_SUFFIX, MANIFEST_SCHEMA, type Manifest, type MergeWarning, type Problem, type ResolvedClaim, SCALAR_TYPES, SET, type ScalarType, type SettingDecl, type StageRename, type Strategy, type TargetDecl, type TreeMergeOptions, type TreeMergeResult, type TypeDecl, UNRESOLVED_KEY, type UnresolvedEntry, VALUE_TYPES, type ValueContext, type ValueType, atIndex, atKey, claimClashes, compileEntry, compiledTarget, defaultOf, effectiveClaim, entryProblems, extensionDataStrategy, keyedBy, manifestProblems, mapOf, markUnresolved, mergeComments, mergeExtensionData, mergeTree, objectOf, orphanedEntries, parseManifest, renameStages, resolvedClaims, settingValues, stableStringify, strategyForTarget, strategyForType, targetOf, unresolvedOf, unresolvedProblems, valueProblems, withoutMark };
|
package/dist/extensions.d.ts
CHANGED
|
@@ -150,6 +150,17 @@ declare function resolvedClaims(manifest: Manifest, host: HostName, chosen?: Rea
|
|
|
150
150
|
declare function claimClashes(claims: readonly ResolvedClaim[]): Problem[];
|
|
151
151
|
/** One manifest's declarations for one host and node kind, or undefined. */
|
|
152
152
|
declare function targetOf(manifest: Manifest | undefined, host: HostName, kind: string): TargetDecl | undefined;
|
|
153
|
+
/**
|
|
154
|
+
* A claim as a host draws and checks its field: the claim's label, help, value help and constraints, over the
|
|
155
|
+
* host's own declaration for what the claim leaves out (an enum's or flags' values, a quality's stages, the
|
|
156
|
+
* default). The host's vocabulary stands when the claim names none, as the host's ladder always does.
|
|
157
|
+
*/
|
|
158
|
+
declare function effectiveClaim<C extends ClaimDecl>(claim: C, hostDecl: {
|
|
159
|
+
readonly type?: string;
|
|
160
|
+
readonly values?: readonly string[];
|
|
161
|
+
readonly stages?: readonly string[];
|
|
162
|
+
readonly default?: unknown;
|
|
163
|
+
}): C;
|
|
153
164
|
|
|
154
165
|
/** What the host knows about its nodes, for references. */
|
|
155
166
|
interface ValueContext {
|
|
@@ -198,6 +209,8 @@ declare function renameStages(target: TargetDecl, entry: Readonly<Record<string,
|
|
|
198
209
|
* sorted by key, or in the authored order with `order: "preserve"`
|
|
199
210
|
* object(fields) named keys by their own strategy, every other key by `other`
|
|
200
211
|
* (atomic when absent)
|
|
212
|
+
* comments a list of comment threads, merged message by message
|
|
213
|
+
* (`mergeComments`)
|
|
201
214
|
*/
|
|
202
215
|
type Strategy = {
|
|
203
216
|
readonly kind: "atomic";
|
|
@@ -216,9 +229,12 @@ type Strategy = {
|
|
|
216
229
|
readonly kind: "object";
|
|
217
230
|
readonly fields: Readonly<Record<string, Strategy>>;
|
|
218
231
|
readonly other?: Strategy;
|
|
232
|
+
} | {
|
|
233
|
+
readonly kind: "comments";
|
|
219
234
|
};
|
|
220
235
|
declare const ATOMIC: Strategy;
|
|
221
236
|
declare const SET: Strategy;
|
|
237
|
+
declare const COMMENTS: Strategy;
|
|
222
238
|
declare const mapOf: (of: Strategy) => Strategy;
|
|
223
239
|
declare const keyedBy: (key: string, of: Strategy, opts?: {
|
|
224
240
|
order?: "sorted" | "preserve";
|
|
@@ -256,6 +272,25 @@ interface TreeMergeOptions {
|
|
|
256
272
|
declare function stableStringify(value: unknown): string;
|
|
257
273
|
/** Three-way merge `base`, `ours` and `theirs` by `strategy`. A clash keeps ours. */
|
|
258
274
|
declare function mergeTree(strategy: Strategy, base: unknown, ours: unknown, theirs: unknown, opts?: TreeMergeOptions): TreeMergeResult;
|
|
275
|
+
/**
|
|
276
|
+
* Three-way merge two lists of comment threads, the shape both families'
|
|
277
|
+
* comments share: `{ id, messages: [{ author, ts, body, deleted? }], resolved?,
|
|
278
|
+
* ...}`. Lifted from Patter's merge (patterkit design/family-parity-2026-10.md
|
|
279
|
+
* item 5), where a thread merged whole made two replies to one thread clash.
|
|
280
|
+
*
|
|
281
|
+
* - Messages are keyed by author and timestamp, and are the union of both
|
|
282
|
+
* sides', oldest first. A withdrawn message (a tombstone: body emptied,
|
|
283
|
+
* `deleted` set) stays withdrawn whichever side withdrew it, and a message a
|
|
284
|
+
* side removed outright, or lost with its whole thread, counts as withdrawn
|
|
285
|
+
* by that side. One message edited two ways is a clash that keeps ours.
|
|
286
|
+
* - A thread's other fields (its anchor, its marker, `resolved`) merge one by
|
|
287
|
+
* one, a field changed two ways being a clash; a thread one side removed
|
|
288
|
+
* takes the other side's.
|
|
289
|
+
* - A thread with nothing readable left goes, as the editors drop it.
|
|
290
|
+
*
|
|
291
|
+
* Threads come back oldest first, by their first message, then by id.
|
|
292
|
+
*/
|
|
293
|
+
declare function mergeComments(base: unknown, ours: unknown, theirs: unknown, opts?: TreeMergeOptions): TreeMergeResult;
|
|
259
294
|
/** How a value of this type merges (the README's table). */
|
|
260
295
|
declare function strategyForType(decl: TypeDecl): Strategy;
|
|
261
296
|
/** How one node's entry merges: field by field, each by its type. */
|
|
@@ -310,4 +345,4 @@ declare const atKey: (base: string, key: string) => string;
|
|
|
310
345
|
/** `base` and then list position `i`. */
|
|
311
346
|
declare const atIndex: (base: string, i: number) => string;
|
|
312
347
|
|
|
313
|
-
export { ATOMIC, type ClaimDecl, type Conflict, type ConflictKind, type DataMergeResult, type ExtensionData, type FieldDecl, HOSTS, type HostName, type HostSpec, type JsonValue, MANIFEST_FILE_SUFFIX, MANIFEST_SCHEMA, type Manifest, type MergeWarning, type Problem, type ResolvedClaim, SCALAR_TYPES, SET, type ScalarType, type SettingDecl, type StageRename, type Strategy, type TargetDecl, type TreeMergeOptions, type TreeMergeResult, type TypeDecl, UNRESOLVED_KEY, type UnresolvedEntry, VALUE_TYPES, type ValueContext, type ValueType, atIndex, atKey, claimClashes, compileEntry, compiledTarget, defaultOf, entryProblems, extensionDataStrategy, keyedBy, manifestProblems, mapOf, markUnresolved, mergeExtensionData, mergeTree, objectOf, orphanedEntries, parseManifest, renameStages, resolvedClaims, settingValues, stableStringify, strategyForTarget, strategyForType, targetOf, unresolvedOf, unresolvedProblems, valueProblems, withoutMark };
|
|
348
|
+
export { ATOMIC, COMMENTS, type ClaimDecl, type Conflict, type ConflictKind, type DataMergeResult, type ExtensionData, type FieldDecl, HOSTS, type HostName, type HostSpec, type JsonValue, MANIFEST_FILE_SUFFIX, MANIFEST_SCHEMA, type Manifest, type MergeWarning, type Problem, type ResolvedClaim, SCALAR_TYPES, SET, type ScalarType, type SettingDecl, type StageRename, type Strategy, type TargetDecl, type TreeMergeOptions, type TreeMergeResult, type TypeDecl, UNRESOLVED_KEY, type UnresolvedEntry, VALUE_TYPES, type ValueContext, type ValueType, atIndex, atKey, claimClashes, compileEntry, compiledTarget, defaultOf, effectiveClaim, entryProblems, extensionDataStrategy, keyedBy, manifestProblems, mapOf, markUnresolved, mergeComments, mergeExtensionData, mergeTree, objectOf, orphanedEntries, parseManifest, renameStages, resolvedClaims, settingValues, stableStringify, strategyForTarget, strategyForType, targetOf, unresolvedOf, unresolvedProblems, valueProblems, withoutMark };
|
package/dist/extensions.js
CHANGED
|
@@ -396,7 +396,7 @@ function targetProblems(host, kind, target, path, settings, out) {
|
|
|
396
396
|
if (!SCALAR_TYPES.includes(claim.type)) {
|
|
397
397
|
out.push(err2("claim-type", atKey(at, "type"), "a claim presents a host field, which is a scalar"));
|
|
398
398
|
} else {
|
|
399
|
-
typeProblems(host, claim, at, false, out);
|
|
399
|
+
typeProblems(host, claim, at, false, out, true);
|
|
400
400
|
}
|
|
401
401
|
if (typeof claim.setting !== "string" || !settings.has(claim.setting)) {
|
|
402
402
|
out.push(err2("claim-setting", atKey(at, "setting"), `a claim names its field through a setting, and "${String(claim.setting)}" is not one of the manifest's settings`));
|
|
@@ -439,7 +439,7 @@ function fieldListProblems(host, fields, path, topLevel, out) {
|
|
|
439
439
|
}
|
|
440
440
|
});
|
|
441
441
|
}
|
|
442
|
-
function typeProblems(host, decl, path, named, out) {
|
|
442
|
+
function typeProblems(host, decl, path, named, out, claim = false) {
|
|
443
443
|
const typeAt = atKey(path, "type");
|
|
444
444
|
if (decl.type === "string") {
|
|
445
445
|
out.push(err2("string-type", typeAt, 'the text type is spelled "text"'));
|
|
@@ -455,6 +455,7 @@ function typeProblems(host, decl, path, named, out) {
|
|
|
455
455
|
case "enum":
|
|
456
456
|
case "flags": {
|
|
457
457
|
const values = decl.values;
|
|
458
|
+
if (claim && values === void 0) break;
|
|
458
459
|
if (!Array.isArray(values) || values.length === 0) {
|
|
459
460
|
out.push(err2("values-empty", at("values"), `an ${decl.type === "enum" ? "enum" : "flags field"} lists its values`));
|
|
460
461
|
sound = false;
|
|
@@ -473,6 +474,7 @@ function typeProblems(host, decl, path, named, out) {
|
|
|
473
474
|
break;
|
|
474
475
|
}
|
|
475
476
|
case "quality": {
|
|
477
|
+
if (claim && decl.stages === void 0) break;
|
|
476
478
|
for (const p of qualityDeclarationProblems(decl.stages)) {
|
|
477
479
|
out.push(err2(
|
|
478
480
|
`quality-${p.kind === "default-not-a-stage" ? "default" : p.kind}`,
|
|
@@ -532,7 +534,11 @@ function typeProblems(host, decl, path, named, out) {
|
|
|
532
534
|
}
|
|
533
535
|
}
|
|
534
536
|
if (decl.renamedStages !== void 0) renamedStagesProblems(decl, at("renamedStages"), out);
|
|
535
|
-
if (decl.valueHelp !== void 0) {
|
|
537
|
+
if (decl.valueHelp !== void 0 && claim) {
|
|
538
|
+
if (!isObject(decl.valueHelp) || !["enum", "flags", "quality"].includes(decl.type)) {
|
|
539
|
+
out.push(err2("value-help", at("valueHelp"), "value help describes the values of an enum or flags field, or a quality's stages"));
|
|
540
|
+
}
|
|
541
|
+
} else if (decl.valueHelp !== void 0) {
|
|
536
542
|
const vocabulary = decl.type === "quality" ? decl.stages : decl.type === "enum" || decl.type === "flags" ? decl.values : void 0;
|
|
537
543
|
if (vocabulary === void 0 || !isObject(decl.valueHelp)) {
|
|
538
544
|
out.push(err2("value-help", at("valueHelp"), "value help describes the values of an enum or flags field, or a quality's stages"));
|
|
@@ -613,10 +619,19 @@ function targetOf(manifest, host, kind) {
|
|
|
613
619
|
const kinds = manifest?.targets[host];
|
|
614
620
|
return kinds !== void 0 && own(kinds, kind) ? kinds[kind] : void 0;
|
|
615
621
|
}
|
|
622
|
+
function effectiveClaim(claim, hostDecl) {
|
|
623
|
+
return {
|
|
624
|
+
...claim,
|
|
625
|
+
...claim.values === void 0 && hostDecl.values !== void 0 ? { values: hostDecl.values } : {},
|
|
626
|
+
...claim.stages === void 0 && hostDecl.stages !== void 0 ? { stages: hostDecl.stages } : {},
|
|
627
|
+
...claim.default === void 0 && hostDecl.default !== void 0 ? { default: hostDecl.default } : {}
|
|
628
|
+
};
|
|
629
|
+
}
|
|
616
630
|
|
|
617
631
|
// src/extensions/merge.ts
|
|
618
632
|
var ATOMIC = { kind: "atomic" };
|
|
619
633
|
var SET = { kind: "set" };
|
|
634
|
+
var COMMENTS = { kind: "comments" };
|
|
620
635
|
var mapOf = (of) => ({ kind: "map", of });
|
|
621
636
|
var keyedBy = (key, of, opts) => ({
|
|
622
637
|
kind: "keyed",
|
|
@@ -659,6 +674,7 @@ function hasShape(spec, v) {
|
|
|
659
674
|
return true;
|
|
660
675
|
case "set":
|
|
661
676
|
case "keyed":
|
|
677
|
+
case "comments":
|
|
662
678
|
return Array.isArray(v);
|
|
663
679
|
case "map":
|
|
664
680
|
case "object":
|
|
@@ -698,6 +714,8 @@ function mergeValue(spec, b, o, t, id, path, ctx) {
|
|
|
698
714
|
}
|
|
699
715
|
case "keyed":
|
|
700
716
|
return mergeKeyed(spec, asArr(b), o, t, path, ctx);
|
|
717
|
+
case "comments":
|
|
718
|
+
return mergeThreads(asArr(b), o, t, path, ctx);
|
|
701
719
|
}
|
|
702
720
|
}
|
|
703
721
|
function mergeKeyed(spec, B, O, T, path, ctx) {
|
|
@@ -776,6 +794,70 @@ function preservedOrder(B, O, T, survivors, path, ctx) {
|
|
|
776
794
|
for (const k of [...survivors.keys()].sort()) if (!result.includes(k)) result.push(k);
|
|
777
795
|
return result;
|
|
778
796
|
}
|
|
797
|
+
function mergeComments(base, ours, theirs, opts) {
|
|
798
|
+
return mergeTree(COMMENTS, base, ours, theirs, opts);
|
|
799
|
+
}
|
|
800
|
+
function mergeThreads(B, O, T, path, ctx) {
|
|
801
|
+
const index = (arr) => {
|
|
802
|
+
const m = /* @__PURE__ */ new Map();
|
|
803
|
+
for (const c of arr) if (isObject(c) && typeof c["id"] === "string") m.set(c["id"], c);
|
|
804
|
+
return m;
|
|
805
|
+
};
|
|
806
|
+
const Bm = index(B), Om = index(O), Tm = index(T);
|
|
807
|
+
const out = [];
|
|
808
|
+
for (const id of /* @__PURE__ */ new Set([...Bm.keys(), ...Om.keys(), ...Tm.keys()])) {
|
|
809
|
+
const b = Bm.get(id), o = Om.get(id), t = Tm.get(id);
|
|
810
|
+
const here = `${path}[${id}]`;
|
|
811
|
+
if (o === void 0 && t === void 0) continue;
|
|
812
|
+
if (![b, o, t].some((c) => Array.isArray(c?.["messages"]))) {
|
|
813
|
+
const v = o !== void 0 && t !== void 0 ? merge3(b, o, t, id, here, ctx) : b !== void 0 && ctx.eq(o ?? t, b) ? void 0 : o ?? t;
|
|
814
|
+
if (isObject(v)) out.push(v);
|
|
815
|
+
continue;
|
|
816
|
+
}
|
|
817
|
+
const messages = mergeMessages(b, o, t, id, here, ctx);
|
|
818
|
+
if (messages.length === 0 || messages.every((m) => m["deleted"] === true)) continue;
|
|
819
|
+
const fields = {};
|
|
820
|
+
if (o !== void 0 && t !== void 0) {
|
|
821
|
+
const B0 = b ?? {};
|
|
822
|
+
const flag = (c, k) => k === "resolved" ? c[k] === true ? true : void 0 : c[k];
|
|
823
|
+
for (const k of /* @__PURE__ */ new Set([...Object.keys(o), ...Object.keys(t), ...Object.keys(B0)])) {
|
|
824
|
+
if (k === "messages") continue;
|
|
825
|
+
const v = merge3(flag(B0, k), flag(o, k), flag(t, k), id, `${here}.${k}`, ctx);
|
|
826
|
+
if (v !== void 0) fields[k] = v;
|
|
827
|
+
}
|
|
828
|
+
} else {
|
|
829
|
+
for (const [k, v] of Object.entries(o ?? t)) if (k !== "messages") fields[k] = v;
|
|
830
|
+
}
|
|
831
|
+
out.push({ ...fields, messages });
|
|
832
|
+
}
|
|
833
|
+
const first = (c) => {
|
|
834
|
+
const m = asArr(c["messages"])[0];
|
|
835
|
+
return isObject(m) && typeof m["ts"] === "string" ? m["ts"] : "";
|
|
836
|
+
};
|
|
837
|
+
return out.sort((x, y) => first(x).localeCompare(first(y)) || String(x["id"]).localeCompare(String(y["id"])));
|
|
838
|
+
}
|
|
839
|
+
function mergeMessages(b, o, t, id, here, ctx) {
|
|
840
|
+
const keyOf = (m) => `${String(m["author"] ?? "")}|${String(m["ts"] ?? "")}`;
|
|
841
|
+
const index = (c) => {
|
|
842
|
+
const m = /* @__PURE__ */ new Map();
|
|
843
|
+
for (const x of asArr(c?.["messages"])) if (isObject(x)) m.set(keyOf(x), x);
|
|
844
|
+
return m;
|
|
845
|
+
};
|
|
846
|
+
const Bm = index(b), Om = index(o), Tm = index(t);
|
|
847
|
+
const out = [];
|
|
848
|
+
for (const k of /* @__PURE__ */ new Set([...Bm.keys(), ...Om.keys(), ...Tm.keys()])) {
|
|
849
|
+
const mb = Bm.get(k), mo = Om.get(k), mt = Tm.get(k);
|
|
850
|
+
if ([mb, mo, mt].some((m) => m?.["deleted"] === true) || mb !== void 0 && (mo === void 0 || mt === void 0)) {
|
|
851
|
+
out.push({ ...mo ?? mt ?? mb, body: "", deleted: true });
|
|
852
|
+
} else if (mo !== void 0 && mt !== void 0) {
|
|
853
|
+
out.push(merge3(mb, mo, mt, id, `${here}.messages[${k}]`, ctx));
|
|
854
|
+
} else {
|
|
855
|
+
out.push(mo ?? mt);
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
const ts = (m) => String(m["ts"] ?? "");
|
|
859
|
+
return out.sort((x, y) => ts(x).localeCompare(ts(y)) || String(x["author"] ?? "").localeCompare(String(y["author"] ?? "")));
|
|
860
|
+
}
|
|
779
861
|
function strategyForType(decl) {
|
|
780
862
|
switch (decl.type) {
|
|
781
863
|
case "flags":
|
|
@@ -883,6 +965,6 @@ function orphanedEntries(data, exists) {
|
|
|
883
965
|
return out;
|
|
884
966
|
}
|
|
885
967
|
|
|
886
|
-
export { ATOMIC, HOSTS, MANIFEST_FILE_SUFFIX, MANIFEST_SCHEMA, SCALAR_TYPES, SET, UNRESOLVED_KEY, VALUE_TYPES, atIndex, atKey, claimClashes, compileEntry, compiledTarget, defaultOf, entryProblems, extensionDataStrategy, keyedBy, manifestProblems, mapOf, markUnresolved, mergeExtensionData, mergeTree, objectOf, orphanedEntries, parseManifest, renameStages, resolvedClaims, settingValues, stableStringify, strategyForTarget, strategyForType, targetOf, unresolvedOf, unresolvedProblems, valueProblems, withoutMark };
|
|
968
|
+
export { ATOMIC, COMMENTS, HOSTS, MANIFEST_FILE_SUFFIX, MANIFEST_SCHEMA, SCALAR_TYPES, SET, UNRESOLVED_KEY, VALUE_TYPES, atIndex, atKey, claimClashes, compileEntry, compiledTarget, defaultOf, effectiveClaim, entryProblems, extensionDataStrategy, keyedBy, manifestProblems, mapOf, markUnresolved, mergeComments, mergeExtensionData, mergeTree, objectOf, orphanedEntries, parseManifest, renameStages, resolvedClaims, settingValues, stableStringify, strategyForTarget, strategyForType, targetOf, unresolvedOf, unresolvedProblems, valueProblems, withoutMark };
|
|
887
969
|
//# sourceMappingURL=extensions.js.map
|
|
888
970
|
//# sourceMappingURL=extensions.js.map
|