@mearie/core 0.6.3 → 0.6.5
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/dist/index.cjs +48 -16
- package/dist/index.mjs +48 -16
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -272,7 +272,10 @@ const dedupExchange = () => {
|
|
|
272
272
|
else operations.set(dedupKey, new Set([op.key]));
|
|
273
273
|
if (!isInflight) resolved.delete(dedupKey);
|
|
274
274
|
return (op.metadata.dedup?.skip ?? false) || !isInflight;
|
|
275
|
-
}), delay(0)
|
|
275
|
+
}), delay(0), require_make.filter((op) => {
|
|
276
|
+
const dedupKey = makeDedupKey(op);
|
|
277
|
+
return operations.get(dedupKey)?.has(op.key) ?? false;
|
|
278
|
+
})), require_make.pipe(ops$, require_make.filter((op) => op.variant === "teardown"), require_make.filter((teardown) => {
|
|
276
279
|
for (const [dedupKey, subs] of operations.entries()) if (subs.delete(teardown.key)) {
|
|
277
280
|
if (subs.size === 0) {
|
|
278
281
|
operations.delete(dedupKey);
|
|
@@ -347,6 +350,26 @@ const makeEntityKey = (typename, keyValues) => {
|
|
|
347
350
|
const resolveArguments = (args, variables) => {
|
|
348
351
|
return Object.fromEntries(Object.entries(args).map(([key, value]) => [key, value.kind === "literal" ? value.value : variables[value.name]]));
|
|
349
352
|
};
|
|
353
|
+
const resolveDirectiveValue = (value, variables) => {
|
|
354
|
+
if (value !== null && typeof value === "object" && "kind" in value) {
|
|
355
|
+
const v = value;
|
|
356
|
+
if (v.kind === "variable" && v.name) return variables[v.name];
|
|
357
|
+
if (v.kind === "literal") return v.value;
|
|
358
|
+
}
|
|
359
|
+
return value;
|
|
360
|
+
};
|
|
361
|
+
/**
|
|
362
|
+
* Determines whether a field should be included based on @skip/@include directives.
|
|
363
|
+
* @internal
|
|
364
|
+
*/
|
|
365
|
+
const shouldIncludeField = (directives, variables) => {
|
|
366
|
+
if (!directives) return true;
|
|
367
|
+
for (const d of directives) {
|
|
368
|
+
if (d.name === "skip" && resolveDirectiveValue(d.args?.if, variables) === true) return false;
|
|
369
|
+
if (d.name === "include" && resolveDirectiveValue(d.args?.if, variables) === false) return false;
|
|
370
|
+
}
|
|
371
|
+
return true;
|
|
372
|
+
};
|
|
350
373
|
/**
|
|
351
374
|
* Generates a cache key for a GraphQL field selection.
|
|
352
375
|
* Always uses the actual field name (not alias) with a stringified representation of the arguments.
|
|
@@ -539,6 +562,13 @@ const resolveTypename = (selections, data) => {
|
|
|
539
562
|
return data.__typename;
|
|
540
563
|
};
|
|
541
564
|
const normalize = (schemaMeta, selections, storage, data, variables, accessor) => {
|
|
565
|
+
const accessorNotified = accessor ? /* @__PURE__ */ new Map() : void 0;
|
|
566
|
+
const callAccessor = (storageKey, fieldKey, oldValue, newValue) => {
|
|
567
|
+
const key = `${storageKey}\0${fieldKey}`;
|
|
568
|
+
if (accessorNotified.has(key) && isEqual(accessorNotified.get(key), newValue)) return;
|
|
569
|
+
accessorNotified.set(key, newValue);
|
|
570
|
+
accessor(storageKey, fieldKey, oldValue, newValue);
|
|
571
|
+
};
|
|
542
572
|
const resolveEntityKey = (typename, data) => {
|
|
543
573
|
if (!typename) return null;
|
|
544
574
|
const entityMeta = schemaMeta.entities[typename];
|
|
@@ -556,6 +586,7 @@ const normalize = (schemaMeta, selections, storage, data, variables, accessor) =
|
|
|
556
586
|
if (entityKey) storageKey = entityKey;
|
|
557
587
|
const fields = {};
|
|
558
588
|
for (const selection of selections) if (selection.kind === "Field") {
|
|
589
|
+
if (!shouldIncludeField(selection.directives, variables)) continue;
|
|
559
590
|
const fieldKey = makeFieldKey(selection, variables);
|
|
560
591
|
let fieldValue = data[selection.alias ?? selection.name];
|
|
561
592
|
if (selection.name === "__typename" && fieldValue === void 0 && typename) fieldValue = typename;
|
|
@@ -564,9 +595,9 @@ const normalize = (schemaMeta, selections, storage, data, variables, accessor) =
|
|
|
564
595
|
if (fieldTypename && schemaMeta.entities[fieldTypename] && !resolveEntityKey(fieldTypename, fieldValue) && isEntityLink(storage[storageKey]?.[fieldKey])) continue;
|
|
565
596
|
}
|
|
566
597
|
const oldValue = storageKey === null ? void 0 : storage[storageKey]?.[fieldKey];
|
|
567
|
-
if (storageKey !== null && (!selection.selections || isNullish(oldValue) || isNullish(fieldValue)))
|
|
598
|
+
if (storageKey !== null && (!selection.selections || isNullish(oldValue) || isNullish(fieldValue))) callAccessor?.(storageKey, fieldKey, oldValue, fieldValue);
|
|
568
599
|
fields[fieldKey] = selection.selections ? normalizeField(null, selection.selections, fieldValue, selection.type) : fieldValue;
|
|
569
|
-
if (storageKey !== null && selection.selections && !isNullish(oldValue) && !isNullish(fieldValue) && !isEntityLink(fields[fieldKey]) && !isEqual(oldValue, fields[fieldKey]))
|
|
600
|
+
if (storageKey !== null && selection.selections && !isNullish(oldValue) && !isNullish(fieldValue) && !isEntityLink(fields[fieldKey]) && !isEqual(oldValue, fields[fieldKey])) callAccessor?.(storageKey, fieldKey, oldValue, fields[fieldKey]);
|
|
570
601
|
} else if (selection.kind === "FragmentSpread" || selection.kind === "InlineFragment" && selection.on === typename) {
|
|
571
602
|
const inner = normalizeField(storageKey, selection.selections, value);
|
|
572
603
|
if (!isEntityLink(inner)) mergeFields(fields, inner);
|
|
@@ -581,10 +612,7 @@ const normalize = (schemaMeta, selections, storage, data, variables, accessor) =
|
|
|
581
612
|
return fields;
|
|
582
613
|
};
|
|
583
614
|
const fields = normalizeField(RootFieldKey, selections, data);
|
|
584
|
-
storage[RootFieldKey]
|
|
585
|
-
...storage[RootFieldKey],
|
|
586
|
-
...fields
|
|
587
|
-
};
|
|
615
|
+
mergeFields(storage[RootFieldKey], fields);
|
|
588
616
|
};
|
|
589
617
|
|
|
590
618
|
//#endregion
|
|
@@ -612,6 +640,7 @@ const denormalize = (selections, storage, value, variables, accessor, options) =
|
|
|
612
640
|
}
|
|
613
641
|
const fields = {};
|
|
614
642
|
for (const selection of selections) if (selection.kind === "Field") {
|
|
643
|
+
if (!shouldIncludeField(selection.directives, variables)) continue;
|
|
615
644
|
const fieldKey = makeFieldKey(selection, variables);
|
|
616
645
|
const fieldValue = data[fieldKey];
|
|
617
646
|
const fieldPath = [...path, selection.alias ?? selection.name];
|
|
@@ -755,6 +784,7 @@ const traceSelections = (selections, storage, value, variables, storageKey, base
|
|
|
755
784
|
}
|
|
756
785
|
const fields = {};
|
|
757
786
|
for (const selection of sels) if (selection.kind === "Field") {
|
|
787
|
+
if (!shouldIncludeField(selection.directives, variables)) continue;
|
|
758
788
|
const fieldKey = makeFieldKey(selection, variables);
|
|
759
789
|
const fieldValue = data[fieldKey];
|
|
760
790
|
const fieldPath = [...path, selection.alias ?? selection.name];
|
|
@@ -946,7 +976,7 @@ const diffSnapshots = (oldData, newData, entityArrayChanges) => {
|
|
|
946
976
|
patches.push(...arrayPatches);
|
|
947
977
|
for (const [i, item] of cur.entries()) {
|
|
948
978
|
const entityKey = newKeys[i];
|
|
949
|
-
|
|
979
|
+
if (entityKey && oldByKey.has(entityKey)) diff(oldByKey.get(entityKey), item, [...path, i]);
|
|
950
980
|
}
|
|
951
981
|
};
|
|
952
982
|
diff(oldData, newData, []);
|
|
@@ -980,7 +1010,7 @@ const classifyChanges = (changes) => {
|
|
|
980
1010
|
/**
|
|
981
1011
|
* @internal
|
|
982
1012
|
*/
|
|
983
|
-
const processScalarChanges = (changes, registry, subscriptions) => {
|
|
1013
|
+
const processScalarChanges = (changes, registry, subscriptions, storage) => {
|
|
984
1014
|
const result = /* @__PURE__ */ new Map();
|
|
985
1015
|
for (const change of changes) {
|
|
986
1016
|
const entries = registry.get(change.depKey);
|
|
@@ -990,8 +1020,9 @@ const processScalarChanges = (changes, registry, subscriptions) => {
|
|
|
990
1020
|
const sub = subscriptions.get(entry.subscriptionId);
|
|
991
1021
|
if (!sub) continue;
|
|
992
1022
|
let patchValue = change.newValue;
|
|
993
|
-
if (entry.selections && isNormalizedRecord(change.newValue)) {
|
|
994
|
-
const
|
|
1023
|
+
if (entry.selections && (isNormalizedRecord(change.newValue) || Array.isArray(change.newValue) && change.newValue.some((v) => isNormalizedRecord(v)))) {
|
|
1024
|
+
const mergedValue = storage[change.storageKey]?.[change.fieldKey] ?? change.newValue;
|
|
1025
|
+
const { data } = denormalize(entry.selections, storage, mergedValue, sub.variables);
|
|
995
1026
|
patchValue = data;
|
|
996
1027
|
}
|
|
997
1028
|
const patches = result.get(entry.subscriptionId) ?? [];
|
|
@@ -1567,10 +1598,11 @@ var Cache = class {
|
|
|
1567
1598
|
*/
|
|
1568
1599
|
hydrate(snapshot) {
|
|
1569
1600
|
const { storage } = snapshot;
|
|
1570
|
-
for (const [key, fields] of Object.entries(storage))
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1601
|
+
for (const [key, fields] of Object.entries(storage)) {
|
|
1602
|
+
const existing = this.#storage[key];
|
|
1603
|
+
if (existing) mergeFields(existing, fields, true);
|
|
1604
|
+
else this.#storage[key] = fields;
|
|
1605
|
+
}
|
|
1574
1606
|
}
|
|
1575
1607
|
/**
|
|
1576
1608
|
* Clears all cache data.
|
|
@@ -1586,7 +1618,7 @@ var Cache = class {
|
|
|
1586
1618
|
if (changes.length === 0) return;
|
|
1587
1619
|
const unstalledPatches = this.#checkStalled(changes);
|
|
1588
1620
|
const { scalar, structural } = classifyChanges(changes);
|
|
1589
|
-
const scalarPatches = processScalarChanges(scalar, this.#registry, this.#subscriptions);
|
|
1621
|
+
const scalarPatches = processScalarChanges(scalar, this.#registry, this.#subscriptions, this.#storage);
|
|
1590
1622
|
const structuralPatches = processStructuralChanges(structural, this.#registry, this.#subscriptions, this.#storage, this.#stalled);
|
|
1591
1623
|
const allPatches = /* @__PURE__ */ new Map();
|
|
1592
1624
|
for (const [subId, patches] of unstalledPatches) allPatches.set(subId, patches);
|
package/dist/index.mjs
CHANGED
|
@@ -271,7 +271,10 @@ const dedupExchange = () => {
|
|
|
271
271
|
else operations.set(dedupKey, new Set([op.key]));
|
|
272
272
|
if (!isInflight) resolved.delete(dedupKey);
|
|
273
273
|
return (op.metadata.dedup?.skip ?? false) || !isInflight;
|
|
274
|
-
}), delay(0)
|
|
274
|
+
}), delay(0), filter((op) => {
|
|
275
|
+
const dedupKey = makeDedupKey(op);
|
|
276
|
+
return operations.get(dedupKey)?.has(op.key) ?? false;
|
|
277
|
+
})), pipe(ops$, filter((op) => op.variant === "teardown"), filter((teardown) => {
|
|
275
278
|
for (const [dedupKey, subs] of operations.entries()) if (subs.delete(teardown.key)) {
|
|
276
279
|
if (subs.size === 0) {
|
|
277
280
|
operations.delete(dedupKey);
|
|
@@ -346,6 +349,26 @@ const makeEntityKey = (typename, keyValues) => {
|
|
|
346
349
|
const resolveArguments = (args, variables) => {
|
|
347
350
|
return Object.fromEntries(Object.entries(args).map(([key, value]) => [key, value.kind === "literal" ? value.value : variables[value.name]]));
|
|
348
351
|
};
|
|
352
|
+
const resolveDirectiveValue = (value, variables) => {
|
|
353
|
+
if (value !== null && typeof value === "object" && "kind" in value) {
|
|
354
|
+
const v = value;
|
|
355
|
+
if (v.kind === "variable" && v.name) return variables[v.name];
|
|
356
|
+
if (v.kind === "literal") return v.value;
|
|
357
|
+
}
|
|
358
|
+
return value;
|
|
359
|
+
};
|
|
360
|
+
/**
|
|
361
|
+
* Determines whether a field should be included based on @skip/@include directives.
|
|
362
|
+
* @internal
|
|
363
|
+
*/
|
|
364
|
+
const shouldIncludeField = (directives, variables) => {
|
|
365
|
+
if (!directives) return true;
|
|
366
|
+
for (const d of directives) {
|
|
367
|
+
if (d.name === "skip" && resolveDirectiveValue(d.args?.if, variables) === true) return false;
|
|
368
|
+
if (d.name === "include" && resolveDirectiveValue(d.args?.if, variables) === false) return false;
|
|
369
|
+
}
|
|
370
|
+
return true;
|
|
371
|
+
};
|
|
349
372
|
/**
|
|
350
373
|
* Generates a cache key for a GraphQL field selection.
|
|
351
374
|
* Always uses the actual field name (not alias) with a stringified representation of the arguments.
|
|
@@ -538,6 +561,13 @@ const resolveTypename = (selections, data) => {
|
|
|
538
561
|
return data.__typename;
|
|
539
562
|
};
|
|
540
563
|
const normalize = (schemaMeta, selections, storage, data, variables, accessor) => {
|
|
564
|
+
const accessorNotified = accessor ? /* @__PURE__ */ new Map() : void 0;
|
|
565
|
+
const callAccessor = (storageKey, fieldKey, oldValue, newValue) => {
|
|
566
|
+
const key = `${storageKey}\0${fieldKey}`;
|
|
567
|
+
if (accessorNotified.has(key) && isEqual(accessorNotified.get(key), newValue)) return;
|
|
568
|
+
accessorNotified.set(key, newValue);
|
|
569
|
+
accessor(storageKey, fieldKey, oldValue, newValue);
|
|
570
|
+
};
|
|
541
571
|
const resolveEntityKey = (typename, data) => {
|
|
542
572
|
if (!typename) return null;
|
|
543
573
|
const entityMeta = schemaMeta.entities[typename];
|
|
@@ -555,6 +585,7 @@ const normalize = (schemaMeta, selections, storage, data, variables, accessor) =
|
|
|
555
585
|
if (entityKey) storageKey = entityKey;
|
|
556
586
|
const fields = {};
|
|
557
587
|
for (const selection of selections) if (selection.kind === "Field") {
|
|
588
|
+
if (!shouldIncludeField(selection.directives, variables)) continue;
|
|
558
589
|
const fieldKey = makeFieldKey(selection, variables);
|
|
559
590
|
let fieldValue = data[selection.alias ?? selection.name];
|
|
560
591
|
if (selection.name === "__typename" && fieldValue === void 0 && typename) fieldValue = typename;
|
|
@@ -563,9 +594,9 @@ const normalize = (schemaMeta, selections, storage, data, variables, accessor) =
|
|
|
563
594
|
if (fieldTypename && schemaMeta.entities[fieldTypename] && !resolveEntityKey(fieldTypename, fieldValue) && isEntityLink(storage[storageKey]?.[fieldKey])) continue;
|
|
564
595
|
}
|
|
565
596
|
const oldValue = storageKey === null ? void 0 : storage[storageKey]?.[fieldKey];
|
|
566
|
-
if (storageKey !== null && (!selection.selections || isNullish(oldValue) || isNullish(fieldValue)))
|
|
597
|
+
if (storageKey !== null && (!selection.selections || isNullish(oldValue) || isNullish(fieldValue))) callAccessor?.(storageKey, fieldKey, oldValue, fieldValue);
|
|
567
598
|
fields[fieldKey] = selection.selections ? normalizeField(null, selection.selections, fieldValue, selection.type) : fieldValue;
|
|
568
|
-
if (storageKey !== null && selection.selections && !isNullish(oldValue) && !isNullish(fieldValue) && !isEntityLink(fields[fieldKey]) && !isEqual(oldValue, fields[fieldKey]))
|
|
599
|
+
if (storageKey !== null && selection.selections && !isNullish(oldValue) && !isNullish(fieldValue) && !isEntityLink(fields[fieldKey]) && !isEqual(oldValue, fields[fieldKey])) callAccessor?.(storageKey, fieldKey, oldValue, fields[fieldKey]);
|
|
569
600
|
} else if (selection.kind === "FragmentSpread" || selection.kind === "InlineFragment" && selection.on === typename) {
|
|
570
601
|
const inner = normalizeField(storageKey, selection.selections, value);
|
|
571
602
|
if (!isEntityLink(inner)) mergeFields(fields, inner);
|
|
@@ -580,10 +611,7 @@ const normalize = (schemaMeta, selections, storage, data, variables, accessor) =
|
|
|
580
611
|
return fields;
|
|
581
612
|
};
|
|
582
613
|
const fields = normalizeField(RootFieldKey, selections, data);
|
|
583
|
-
storage[RootFieldKey]
|
|
584
|
-
...storage[RootFieldKey],
|
|
585
|
-
...fields
|
|
586
|
-
};
|
|
614
|
+
mergeFields(storage[RootFieldKey], fields);
|
|
587
615
|
};
|
|
588
616
|
|
|
589
617
|
//#endregion
|
|
@@ -611,6 +639,7 @@ const denormalize = (selections, storage, value, variables, accessor, options) =
|
|
|
611
639
|
}
|
|
612
640
|
const fields = {};
|
|
613
641
|
for (const selection of selections) if (selection.kind === "Field") {
|
|
642
|
+
if (!shouldIncludeField(selection.directives, variables)) continue;
|
|
614
643
|
const fieldKey = makeFieldKey(selection, variables);
|
|
615
644
|
const fieldValue = data[fieldKey];
|
|
616
645
|
const fieldPath = [...path, selection.alias ?? selection.name];
|
|
@@ -754,6 +783,7 @@ const traceSelections = (selections, storage, value, variables, storageKey, base
|
|
|
754
783
|
}
|
|
755
784
|
const fields = {};
|
|
756
785
|
for (const selection of sels) if (selection.kind === "Field") {
|
|
786
|
+
if (!shouldIncludeField(selection.directives, variables)) continue;
|
|
757
787
|
const fieldKey = makeFieldKey(selection, variables);
|
|
758
788
|
const fieldValue = data[fieldKey];
|
|
759
789
|
const fieldPath = [...path, selection.alias ?? selection.name];
|
|
@@ -945,7 +975,7 @@ const diffSnapshots = (oldData, newData, entityArrayChanges) => {
|
|
|
945
975
|
patches.push(...arrayPatches);
|
|
946
976
|
for (const [i, item] of cur.entries()) {
|
|
947
977
|
const entityKey = newKeys[i];
|
|
948
|
-
|
|
978
|
+
if (entityKey && oldByKey.has(entityKey)) diff(oldByKey.get(entityKey), item, [...path, i]);
|
|
949
979
|
}
|
|
950
980
|
};
|
|
951
981
|
diff(oldData, newData, []);
|
|
@@ -979,7 +1009,7 @@ const classifyChanges = (changes) => {
|
|
|
979
1009
|
/**
|
|
980
1010
|
* @internal
|
|
981
1011
|
*/
|
|
982
|
-
const processScalarChanges = (changes, registry, subscriptions) => {
|
|
1012
|
+
const processScalarChanges = (changes, registry, subscriptions, storage) => {
|
|
983
1013
|
const result = /* @__PURE__ */ new Map();
|
|
984
1014
|
for (const change of changes) {
|
|
985
1015
|
const entries = registry.get(change.depKey);
|
|
@@ -989,8 +1019,9 @@ const processScalarChanges = (changes, registry, subscriptions) => {
|
|
|
989
1019
|
const sub = subscriptions.get(entry.subscriptionId);
|
|
990
1020
|
if (!sub) continue;
|
|
991
1021
|
let patchValue = change.newValue;
|
|
992
|
-
if (entry.selections && isNormalizedRecord(change.newValue)) {
|
|
993
|
-
const
|
|
1022
|
+
if (entry.selections && (isNormalizedRecord(change.newValue) || Array.isArray(change.newValue) && change.newValue.some((v) => isNormalizedRecord(v)))) {
|
|
1023
|
+
const mergedValue = storage[change.storageKey]?.[change.fieldKey] ?? change.newValue;
|
|
1024
|
+
const { data } = denormalize(entry.selections, storage, mergedValue, sub.variables);
|
|
994
1025
|
patchValue = data;
|
|
995
1026
|
}
|
|
996
1027
|
const patches = result.get(entry.subscriptionId) ?? [];
|
|
@@ -1566,10 +1597,11 @@ var Cache = class {
|
|
|
1566
1597
|
*/
|
|
1567
1598
|
hydrate(snapshot) {
|
|
1568
1599
|
const { storage } = snapshot;
|
|
1569
|
-
for (const [key, fields] of Object.entries(storage))
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1600
|
+
for (const [key, fields] of Object.entries(storage)) {
|
|
1601
|
+
const existing = this.#storage[key];
|
|
1602
|
+
if (existing) mergeFields(existing, fields, true);
|
|
1603
|
+
else this.#storage[key] = fields;
|
|
1604
|
+
}
|
|
1573
1605
|
}
|
|
1574
1606
|
/**
|
|
1575
1607
|
* Clears all cache data.
|
|
@@ -1585,7 +1617,7 @@ var Cache = class {
|
|
|
1585
1617
|
if (changes.length === 0) return;
|
|
1586
1618
|
const unstalledPatches = this.#checkStalled(changes);
|
|
1587
1619
|
const { scalar, structural } = classifyChanges(changes);
|
|
1588
|
-
const scalarPatches = processScalarChanges(scalar, this.#registry, this.#subscriptions);
|
|
1620
|
+
const scalarPatches = processScalarChanges(scalar, this.#registry, this.#subscriptions, this.#storage);
|
|
1589
1621
|
const structuralPatches = processStructuralChanges(structural, this.#registry, this.#subscriptions, this.#storage, this.#stalled);
|
|
1590
1622
|
const allPatches = /* @__PURE__ */ new Map();
|
|
1591
1623
|
for (const [subId, patches] of unstalledPatches) allPatches.set(subId, patches);
|