@mearie/core 0.6.2 → 0.6.4
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 +56 -35
- package/dist/index.mjs +56 -35
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -347,6 +347,26 @@ const makeEntityKey = (typename, keyValues) => {
|
|
|
347
347
|
const resolveArguments = (args, variables) => {
|
|
348
348
|
return Object.fromEntries(Object.entries(args).map(([key, value]) => [key, value.kind === "literal" ? value.value : variables[value.name]]));
|
|
349
349
|
};
|
|
350
|
+
const resolveDirectiveValue = (value, variables) => {
|
|
351
|
+
if (value !== null && typeof value === "object" && "kind" in value) {
|
|
352
|
+
const v = value;
|
|
353
|
+
if (v.kind === "variable" && v.name) return variables[v.name];
|
|
354
|
+
if (v.kind === "literal") return v.value;
|
|
355
|
+
}
|
|
356
|
+
return value;
|
|
357
|
+
};
|
|
358
|
+
/**
|
|
359
|
+
* Determines whether a field should be included based on @skip/@include directives.
|
|
360
|
+
* @internal
|
|
361
|
+
*/
|
|
362
|
+
const shouldIncludeField = (directives, variables) => {
|
|
363
|
+
if (!directives) return true;
|
|
364
|
+
for (const d of directives) {
|
|
365
|
+
if (d.name === "skip" && resolveDirectiveValue(d.args?.if, variables) === true) return false;
|
|
366
|
+
if (d.name === "include" && resolveDirectiveValue(d.args?.if, variables) === false) return false;
|
|
367
|
+
}
|
|
368
|
+
return true;
|
|
369
|
+
};
|
|
350
370
|
/**
|
|
351
371
|
* Generates a cache key for a GraphQL field selection.
|
|
352
372
|
* Always uses the actual field name (not alias) with a stringified representation of the arguments.
|
|
@@ -556,6 +576,7 @@ const normalize = (schemaMeta, selections, storage, data, variables, accessor) =
|
|
|
556
576
|
if (entityKey) storageKey = entityKey;
|
|
557
577
|
const fields = {};
|
|
558
578
|
for (const selection of selections) if (selection.kind === "Field") {
|
|
579
|
+
if (!shouldIncludeField(selection.directives, variables)) continue;
|
|
559
580
|
const fieldKey = makeFieldKey(selection, variables);
|
|
560
581
|
let fieldValue = data[selection.alias ?? selection.name];
|
|
561
582
|
if (selection.name === "__typename" && fieldValue === void 0 && typename) fieldValue = typename;
|
|
@@ -612,6 +633,7 @@ const denormalize = (selections, storage, value, variables, accessor, options) =
|
|
|
612
633
|
}
|
|
613
634
|
const fields = {};
|
|
614
635
|
for (const selection of selections) if (selection.kind === "Field") {
|
|
636
|
+
if (!shouldIncludeField(selection.directives, variables)) continue;
|
|
615
637
|
const fieldKey = makeFieldKey(selection, variables);
|
|
616
638
|
const fieldValue = data[fieldKey];
|
|
617
639
|
const fieldPath = [...path, selection.alias ?? selection.name];
|
|
@@ -713,6 +735,29 @@ const traceSelections = (selections, storage, value, variables, storageKey, base
|
|
|
713
735
|
const cursors = [];
|
|
714
736
|
const missingDeps = /* @__PURE__ */ new Set();
|
|
715
737
|
let complete = true;
|
|
738
|
+
const traceFragmentSpread = (selection, refKey, value, traceKey, fields, path) => {
|
|
739
|
+
fields[FragmentRefKey] = refKey;
|
|
740
|
+
const merged = selection.args ? {
|
|
741
|
+
...variables,
|
|
742
|
+
...resolveArguments(selection.args, variables)
|
|
743
|
+
} : { ...variables };
|
|
744
|
+
fields[FragmentVarsKey] = {
|
|
745
|
+
...fields[FragmentVarsKey],
|
|
746
|
+
[selection.name]: merged
|
|
747
|
+
};
|
|
748
|
+
const inner = traceSelections(selection.selections, storage, value, variables, traceKey, path, subscriptionId);
|
|
749
|
+
for (const cursor of inner.cursors) cursors.push({
|
|
750
|
+
depKey: cursor.depKey,
|
|
751
|
+
entry: cursor.entry.dependency === "transitive" ? cursor.entry : {
|
|
752
|
+
...cursor.entry,
|
|
753
|
+
dependency: "transitive"
|
|
754
|
+
}
|
|
755
|
+
});
|
|
756
|
+
if (!inner.complete) {
|
|
757
|
+
complete = false;
|
|
758
|
+
for (const dep of inner.missingDeps) missingDeps.add(dep);
|
|
759
|
+
}
|
|
760
|
+
};
|
|
716
761
|
const traceField = (sk, sels, val, path, trackCursors) => {
|
|
717
762
|
if (isNullish(val)) return val;
|
|
718
763
|
if (Array.isArray(val)) return val.map((item, i) => traceField(sk, sels, item, [...path, i], trackCursors));
|
|
@@ -732,6 +777,7 @@ const traceSelections = (selections, storage, value, variables, storageKey, base
|
|
|
732
777
|
}
|
|
733
778
|
const fields = {};
|
|
734
779
|
for (const selection of sels) if (selection.kind === "Field") {
|
|
780
|
+
if (!shouldIncludeField(selection.directives, variables)) continue;
|
|
735
781
|
const fieldKey = makeFieldKey(selection, variables);
|
|
736
782
|
const fieldValue = data[fieldKey];
|
|
737
783
|
const fieldPath = [...path, selection.alias ?? selection.name];
|
|
@@ -740,6 +786,7 @@ const traceSelections = (selections, storage, value, variables, storageKey, base
|
|
|
740
786
|
const entry = {
|
|
741
787
|
subscriptionId,
|
|
742
788
|
path: fieldPath,
|
|
789
|
+
dependency: "direct",
|
|
743
790
|
...selection.selections && { selections: selection.selections }
|
|
744
791
|
};
|
|
745
792
|
cursors.push({
|
|
@@ -759,37 +806,9 @@ const traceSelections = (selections, storage, value, variables, storageKey, base
|
|
|
759
806
|
const resolvedValue = selection.selections ? traceField(null, selection.selections, fieldValue, fieldPath, trackCursors) : fieldValue;
|
|
760
807
|
if (name in fields) mergeFields(fields, { [name]: resolvedValue }, true);
|
|
761
808
|
else fields[name] = resolvedValue;
|
|
762
|
-
} else if (selection.kind === "FragmentSpread") if (sk !== null && sk !== RootFieldKey)
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
...variables,
|
|
766
|
-
...resolveArguments(selection.args, variables)
|
|
767
|
-
} : { ...variables };
|
|
768
|
-
fields[FragmentVarsKey] = {
|
|
769
|
-
...fields[FragmentVarsKey],
|
|
770
|
-
[selection.name]: merged
|
|
771
|
-
};
|
|
772
|
-
const inner = traceSelections(selection.selections, storage, storage[sk], variables, sk, path, subscriptionId);
|
|
773
|
-
if (!inner.complete) {
|
|
774
|
-
complete = false;
|
|
775
|
-
for (const dep of inner.missingDeps) missingDeps.add(dep);
|
|
776
|
-
}
|
|
777
|
-
} else if (sk === RootFieldKey) {
|
|
778
|
-
fields[FragmentRefKey] = RootFieldKey;
|
|
779
|
-
const merged = selection.args ? {
|
|
780
|
-
...variables,
|
|
781
|
-
...resolveArguments(selection.args, variables)
|
|
782
|
-
} : { ...variables };
|
|
783
|
-
fields[FragmentVarsKey] = {
|
|
784
|
-
...fields[FragmentVarsKey],
|
|
785
|
-
[selection.name]: merged
|
|
786
|
-
};
|
|
787
|
-
const inner = traceSelections(selection.selections, storage, storage[RootFieldKey], variables, RootFieldKey, path, subscriptionId);
|
|
788
|
-
if (!inner.complete) {
|
|
789
|
-
complete = false;
|
|
790
|
-
for (const dep of inner.missingDeps) missingDeps.add(dep);
|
|
791
|
-
}
|
|
792
|
-
} else mergeFields(fields, traceField(sk, selection.selections, val, path, trackCursors), true);
|
|
809
|
+
} else if (selection.kind === "FragmentSpread") if (sk !== null && sk !== RootFieldKey) traceFragmentSpread(selection, sk, storage[sk], sk, fields, path);
|
|
810
|
+
else if (sk === RootFieldKey) traceFragmentSpread(selection, RootFieldKey, storage[RootFieldKey], RootFieldKey, fields, path);
|
|
811
|
+
else mergeFields(fields, traceField(sk, selection.selections, val, path, trackCursors), true);
|
|
793
812
|
else if (selection.kind === "InlineFragment" && selection.on === data[typenameFieldKey]) mergeFields(fields, traceField(sk, selection.selections, val, path, trackCursors), true);
|
|
794
813
|
return fields;
|
|
795
814
|
};
|
|
@@ -984,17 +1003,19 @@ const classifyChanges = (changes) => {
|
|
|
984
1003
|
/**
|
|
985
1004
|
* @internal
|
|
986
1005
|
*/
|
|
987
|
-
const processScalarChanges = (changes, registry, subscriptions) => {
|
|
1006
|
+
const processScalarChanges = (changes, registry, subscriptions, storage) => {
|
|
988
1007
|
const result = /* @__PURE__ */ new Map();
|
|
989
1008
|
for (const change of changes) {
|
|
990
1009
|
const entries = registry.get(change.depKey);
|
|
991
1010
|
if (!entries) continue;
|
|
992
1011
|
for (const entry of entries) {
|
|
1012
|
+
if (entry.dependency === "transitive") continue;
|
|
993
1013
|
const sub = subscriptions.get(entry.subscriptionId);
|
|
994
1014
|
if (!sub) continue;
|
|
995
1015
|
let patchValue = change.newValue;
|
|
996
|
-
if (entry.selections && isNormalizedRecord(change.newValue)) {
|
|
997
|
-
const
|
|
1016
|
+
if (entry.selections && (isNormalizedRecord(change.newValue) || Array.isArray(change.newValue) && change.newValue.some((v) => isNormalizedRecord(v)))) {
|
|
1017
|
+
const mergedValue = storage[change.storageKey]?.[change.fieldKey] ?? change.newValue;
|
|
1018
|
+
const { data } = denormalize(entry.selections, {}, mergedValue, sub.variables);
|
|
998
1019
|
patchValue = data;
|
|
999
1020
|
}
|
|
1000
1021
|
const patches = result.get(entry.subscriptionId) ?? [];
|
|
@@ -1589,7 +1610,7 @@ var Cache = class {
|
|
|
1589
1610
|
if (changes.length === 0) return;
|
|
1590
1611
|
const unstalledPatches = this.#checkStalled(changes);
|
|
1591
1612
|
const { scalar, structural } = classifyChanges(changes);
|
|
1592
|
-
const scalarPatches = processScalarChanges(scalar, this.#registry, this.#subscriptions);
|
|
1613
|
+
const scalarPatches = processScalarChanges(scalar, this.#registry, this.#subscriptions, this.#storage);
|
|
1593
1614
|
const structuralPatches = processStructuralChanges(structural, this.#registry, this.#subscriptions, this.#storage, this.#stalled);
|
|
1594
1615
|
const allPatches = /* @__PURE__ */ new Map();
|
|
1595
1616
|
for (const [subId, patches] of unstalledPatches) allPatches.set(subId, patches);
|
package/dist/index.mjs
CHANGED
|
@@ -346,6 +346,26 @@ const makeEntityKey = (typename, keyValues) => {
|
|
|
346
346
|
const resolveArguments = (args, variables) => {
|
|
347
347
|
return Object.fromEntries(Object.entries(args).map(([key, value]) => [key, value.kind === "literal" ? value.value : variables[value.name]]));
|
|
348
348
|
};
|
|
349
|
+
const resolveDirectiveValue = (value, variables) => {
|
|
350
|
+
if (value !== null && typeof value === "object" && "kind" in value) {
|
|
351
|
+
const v = value;
|
|
352
|
+
if (v.kind === "variable" && v.name) return variables[v.name];
|
|
353
|
+
if (v.kind === "literal") return v.value;
|
|
354
|
+
}
|
|
355
|
+
return value;
|
|
356
|
+
};
|
|
357
|
+
/**
|
|
358
|
+
* Determines whether a field should be included based on @skip/@include directives.
|
|
359
|
+
* @internal
|
|
360
|
+
*/
|
|
361
|
+
const shouldIncludeField = (directives, variables) => {
|
|
362
|
+
if (!directives) return true;
|
|
363
|
+
for (const d of directives) {
|
|
364
|
+
if (d.name === "skip" && resolveDirectiveValue(d.args?.if, variables) === true) return false;
|
|
365
|
+
if (d.name === "include" && resolveDirectiveValue(d.args?.if, variables) === false) return false;
|
|
366
|
+
}
|
|
367
|
+
return true;
|
|
368
|
+
};
|
|
349
369
|
/**
|
|
350
370
|
* Generates a cache key for a GraphQL field selection.
|
|
351
371
|
* Always uses the actual field name (not alias) with a stringified representation of the arguments.
|
|
@@ -555,6 +575,7 @@ const normalize = (schemaMeta, selections, storage, data, variables, accessor) =
|
|
|
555
575
|
if (entityKey) storageKey = entityKey;
|
|
556
576
|
const fields = {};
|
|
557
577
|
for (const selection of selections) if (selection.kind === "Field") {
|
|
578
|
+
if (!shouldIncludeField(selection.directives, variables)) continue;
|
|
558
579
|
const fieldKey = makeFieldKey(selection, variables);
|
|
559
580
|
let fieldValue = data[selection.alias ?? selection.name];
|
|
560
581
|
if (selection.name === "__typename" && fieldValue === void 0 && typename) fieldValue = typename;
|
|
@@ -611,6 +632,7 @@ const denormalize = (selections, storage, value, variables, accessor, options) =
|
|
|
611
632
|
}
|
|
612
633
|
const fields = {};
|
|
613
634
|
for (const selection of selections) if (selection.kind === "Field") {
|
|
635
|
+
if (!shouldIncludeField(selection.directives, variables)) continue;
|
|
614
636
|
const fieldKey = makeFieldKey(selection, variables);
|
|
615
637
|
const fieldValue = data[fieldKey];
|
|
616
638
|
const fieldPath = [...path, selection.alias ?? selection.name];
|
|
@@ -712,6 +734,29 @@ const traceSelections = (selections, storage, value, variables, storageKey, base
|
|
|
712
734
|
const cursors = [];
|
|
713
735
|
const missingDeps = /* @__PURE__ */ new Set();
|
|
714
736
|
let complete = true;
|
|
737
|
+
const traceFragmentSpread = (selection, refKey, value, traceKey, fields, path) => {
|
|
738
|
+
fields[FragmentRefKey] = refKey;
|
|
739
|
+
const merged = selection.args ? {
|
|
740
|
+
...variables,
|
|
741
|
+
...resolveArguments(selection.args, variables)
|
|
742
|
+
} : { ...variables };
|
|
743
|
+
fields[FragmentVarsKey] = {
|
|
744
|
+
...fields[FragmentVarsKey],
|
|
745
|
+
[selection.name]: merged
|
|
746
|
+
};
|
|
747
|
+
const inner = traceSelections(selection.selections, storage, value, variables, traceKey, path, subscriptionId);
|
|
748
|
+
for (const cursor of inner.cursors) cursors.push({
|
|
749
|
+
depKey: cursor.depKey,
|
|
750
|
+
entry: cursor.entry.dependency === "transitive" ? cursor.entry : {
|
|
751
|
+
...cursor.entry,
|
|
752
|
+
dependency: "transitive"
|
|
753
|
+
}
|
|
754
|
+
});
|
|
755
|
+
if (!inner.complete) {
|
|
756
|
+
complete = false;
|
|
757
|
+
for (const dep of inner.missingDeps) missingDeps.add(dep);
|
|
758
|
+
}
|
|
759
|
+
};
|
|
715
760
|
const traceField = (sk, sels, val, path, trackCursors) => {
|
|
716
761
|
if (isNullish(val)) return val;
|
|
717
762
|
if (Array.isArray(val)) return val.map((item, i) => traceField(sk, sels, item, [...path, i], trackCursors));
|
|
@@ -731,6 +776,7 @@ const traceSelections = (selections, storage, value, variables, storageKey, base
|
|
|
731
776
|
}
|
|
732
777
|
const fields = {};
|
|
733
778
|
for (const selection of sels) if (selection.kind === "Field") {
|
|
779
|
+
if (!shouldIncludeField(selection.directives, variables)) continue;
|
|
734
780
|
const fieldKey = makeFieldKey(selection, variables);
|
|
735
781
|
const fieldValue = data[fieldKey];
|
|
736
782
|
const fieldPath = [...path, selection.alias ?? selection.name];
|
|
@@ -739,6 +785,7 @@ const traceSelections = (selections, storage, value, variables, storageKey, base
|
|
|
739
785
|
const entry = {
|
|
740
786
|
subscriptionId,
|
|
741
787
|
path: fieldPath,
|
|
788
|
+
dependency: "direct",
|
|
742
789
|
...selection.selections && { selections: selection.selections }
|
|
743
790
|
};
|
|
744
791
|
cursors.push({
|
|
@@ -758,37 +805,9 @@ const traceSelections = (selections, storage, value, variables, storageKey, base
|
|
|
758
805
|
const resolvedValue = selection.selections ? traceField(null, selection.selections, fieldValue, fieldPath, trackCursors) : fieldValue;
|
|
759
806
|
if (name in fields) mergeFields(fields, { [name]: resolvedValue }, true);
|
|
760
807
|
else fields[name] = resolvedValue;
|
|
761
|
-
} else if (selection.kind === "FragmentSpread") if (sk !== null && sk !== RootFieldKey)
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
...variables,
|
|
765
|
-
...resolveArguments(selection.args, variables)
|
|
766
|
-
} : { ...variables };
|
|
767
|
-
fields[FragmentVarsKey] = {
|
|
768
|
-
...fields[FragmentVarsKey],
|
|
769
|
-
[selection.name]: merged
|
|
770
|
-
};
|
|
771
|
-
const inner = traceSelections(selection.selections, storage, storage[sk], variables, sk, path, subscriptionId);
|
|
772
|
-
if (!inner.complete) {
|
|
773
|
-
complete = false;
|
|
774
|
-
for (const dep of inner.missingDeps) missingDeps.add(dep);
|
|
775
|
-
}
|
|
776
|
-
} else if (sk === RootFieldKey) {
|
|
777
|
-
fields[FragmentRefKey] = RootFieldKey;
|
|
778
|
-
const merged = selection.args ? {
|
|
779
|
-
...variables,
|
|
780
|
-
...resolveArguments(selection.args, variables)
|
|
781
|
-
} : { ...variables };
|
|
782
|
-
fields[FragmentVarsKey] = {
|
|
783
|
-
...fields[FragmentVarsKey],
|
|
784
|
-
[selection.name]: merged
|
|
785
|
-
};
|
|
786
|
-
const inner = traceSelections(selection.selections, storage, storage[RootFieldKey], variables, RootFieldKey, path, subscriptionId);
|
|
787
|
-
if (!inner.complete) {
|
|
788
|
-
complete = false;
|
|
789
|
-
for (const dep of inner.missingDeps) missingDeps.add(dep);
|
|
790
|
-
}
|
|
791
|
-
} else mergeFields(fields, traceField(sk, selection.selections, val, path, trackCursors), true);
|
|
808
|
+
} else if (selection.kind === "FragmentSpread") if (sk !== null && sk !== RootFieldKey) traceFragmentSpread(selection, sk, storage[sk], sk, fields, path);
|
|
809
|
+
else if (sk === RootFieldKey) traceFragmentSpread(selection, RootFieldKey, storage[RootFieldKey], RootFieldKey, fields, path);
|
|
810
|
+
else mergeFields(fields, traceField(sk, selection.selections, val, path, trackCursors), true);
|
|
792
811
|
else if (selection.kind === "InlineFragment" && selection.on === data[typenameFieldKey]) mergeFields(fields, traceField(sk, selection.selections, val, path, trackCursors), true);
|
|
793
812
|
return fields;
|
|
794
813
|
};
|
|
@@ -983,17 +1002,19 @@ const classifyChanges = (changes) => {
|
|
|
983
1002
|
/**
|
|
984
1003
|
* @internal
|
|
985
1004
|
*/
|
|
986
|
-
const processScalarChanges = (changes, registry, subscriptions) => {
|
|
1005
|
+
const processScalarChanges = (changes, registry, subscriptions, storage) => {
|
|
987
1006
|
const result = /* @__PURE__ */ new Map();
|
|
988
1007
|
for (const change of changes) {
|
|
989
1008
|
const entries = registry.get(change.depKey);
|
|
990
1009
|
if (!entries) continue;
|
|
991
1010
|
for (const entry of entries) {
|
|
1011
|
+
if (entry.dependency === "transitive") continue;
|
|
992
1012
|
const sub = subscriptions.get(entry.subscriptionId);
|
|
993
1013
|
if (!sub) continue;
|
|
994
1014
|
let patchValue = change.newValue;
|
|
995
|
-
if (entry.selections && isNormalizedRecord(change.newValue)) {
|
|
996
|
-
const
|
|
1015
|
+
if (entry.selections && (isNormalizedRecord(change.newValue) || Array.isArray(change.newValue) && change.newValue.some((v) => isNormalizedRecord(v)))) {
|
|
1016
|
+
const mergedValue = storage[change.storageKey]?.[change.fieldKey] ?? change.newValue;
|
|
1017
|
+
const { data } = denormalize(entry.selections, {}, mergedValue, sub.variables);
|
|
997
1018
|
patchValue = data;
|
|
998
1019
|
}
|
|
999
1020
|
const patches = result.get(entry.subscriptionId) ?? [];
|
|
@@ -1588,7 +1609,7 @@ var Cache = class {
|
|
|
1588
1609
|
if (changes.length === 0) return;
|
|
1589
1610
|
const unstalledPatches = this.#checkStalled(changes);
|
|
1590
1611
|
const { scalar, structural } = classifyChanges(changes);
|
|
1591
|
-
const scalarPatches = processScalarChanges(scalar, this.#registry, this.#subscriptions);
|
|
1612
|
+
const scalarPatches = processScalarChanges(scalar, this.#registry, this.#subscriptions, this.#storage);
|
|
1592
1613
|
const structuralPatches = processStructuralChanges(structural, this.#registry, this.#subscriptions, this.#storage, this.#stalled);
|
|
1593
1614
|
const allPatches = /* @__PURE__ */ new Map();
|
|
1594
1615
|
for (const [subId, patches] of unstalledPatches) allPatches.set(subId, patches);
|