@mearie/core 0.2.4 → 0.3.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.
- package/dist/index.cjs +89 -85
- package/dist/index.d.cts +8 -2
- package/dist/index.d.mts +8 -2
- package/dist/index.mjs +89 -85
- package/package.json +11 -4
package/dist/index.cjs
CHANGED
|
@@ -594,8 +594,10 @@ const denormalize = (selections, storage, value, variables, accessor) => {
|
|
|
594
594
|
const value = selection.selections ? denormalizeField(null, selection.selections, fieldValue) : fieldValue;
|
|
595
595
|
if (name in fields) mergeFields(fields, { [name]: value });
|
|
596
596
|
else fields[name] = value;
|
|
597
|
-
} else if (selection.kind === "FragmentSpread") if (storageKey !== null && storageKey !== RootFieldKey)
|
|
598
|
-
|
|
597
|
+
} else if (selection.kind === "FragmentSpread") if (storageKey !== null && storageKey !== RootFieldKey) {
|
|
598
|
+
fields[FragmentRefKey] = storageKey;
|
|
599
|
+
if (accessor) denormalize(selection.selections, storage, { [EntityLinkKey]: storageKey }, variables, accessor);
|
|
600
|
+
} else mergeFields(fields, denormalizeField(storageKey, selection.selections, value));
|
|
599
601
|
else if (selection.kind === "InlineFragment" && selection.on === data[typenameFieldKey]) mergeFields(fields, denormalizeField(storageKey, selection.selections, value));
|
|
600
602
|
return fields;
|
|
601
603
|
};
|
|
@@ -616,6 +618,7 @@ var Cache = class {
|
|
|
616
618
|
#storage = { [RootFieldKey]: {} };
|
|
617
619
|
#subscriptions = /* @__PURE__ */ new Map();
|
|
618
620
|
#memo = /* @__PURE__ */ new Map();
|
|
621
|
+
#stale = /* @__PURE__ */ new Set();
|
|
619
622
|
constructor(schemaMetadata) {
|
|
620
623
|
this.#schemaMeta = schemaMetadata;
|
|
621
624
|
}
|
|
@@ -628,17 +631,19 @@ var Cache = class {
|
|
|
628
631
|
writeQuery(artifact, variables, data) {
|
|
629
632
|
const dependencies = /* @__PURE__ */ new Set();
|
|
630
633
|
const subscriptions = /* @__PURE__ */ new Set();
|
|
634
|
+
const entityStaleCleared = /* @__PURE__ */ new Set();
|
|
631
635
|
normalize(this.#schemaMeta, artifact.selections, this.#storage, data, variables, (storageKey, fieldKey, oldValue, newValue) => {
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
+
const depKey = makeDependencyKey(storageKey, fieldKey);
|
|
637
|
+
if (this.#stale.delete(depKey)) dependencies.add(depKey);
|
|
638
|
+
if (!entityStaleCleared.has(storageKey) && this.#stale.delete(storageKey)) entityStaleCleared.add(storageKey);
|
|
639
|
+
if (oldValue !== newValue) dependencies.add(depKey);
|
|
636
640
|
});
|
|
641
|
+
for (const entityKey of entityStaleCleared) this.#collectSubscriptions(entityKey, void 0, subscriptions);
|
|
637
642
|
for (const dependency of dependencies) {
|
|
638
643
|
const ss = this.#subscriptions.get(dependency);
|
|
639
644
|
if (ss) for (const s of ss) subscriptions.add(s);
|
|
640
645
|
}
|
|
641
|
-
for (const subscription of subscriptions) subscription.listener(
|
|
646
|
+
for (const subscription of subscriptions) subscription.listener();
|
|
642
647
|
}
|
|
643
648
|
/**
|
|
644
649
|
* Reads a query result from the cache, denormalizing entities if available.
|
|
@@ -648,13 +653,22 @@ var Cache = class {
|
|
|
648
653
|
* @returns Denormalized query result or null if not found.
|
|
649
654
|
*/
|
|
650
655
|
readQuery(artifact, variables) {
|
|
651
|
-
|
|
652
|
-
|
|
656
|
+
let stale = false;
|
|
657
|
+
const { data, partial } = denormalize(artifact.selections, this.#storage, this.#storage[RootFieldKey], variables, (storageKey, fieldKey) => {
|
|
658
|
+
if (this.#stale.has(storageKey) || this.#stale.has(makeDependencyKey(storageKey, fieldKey))) stale = true;
|
|
659
|
+
});
|
|
660
|
+
if (partial) return {
|
|
661
|
+
data: null,
|
|
662
|
+
stale: false
|
|
663
|
+
};
|
|
653
664
|
const key = makeMemoKey("query", artifact.name, stringify(variables));
|
|
654
665
|
const prev = this.#memo.get(key);
|
|
655
666
|
const result = prev === void 0 ? data : replaceEqualDeep(prev, data);
|
|
656
667
|
this.#memo.set(key, result);
|
|
657
|
-
return
|
|
668
|
+
return {
|
|
669
|
+
data: result,
|
|
670
|
+
stale
|
|
671
|
+
};
|
|
658
672
|
}
|
|
659
673
|
/**
|
|
660
674
|
* Subscribes to cache invalidations for a specific query.
|
|
@@ -680,14 +694,26 @@ var Cache = class {
|
|
|
680
694
|
*/
|
|
681
695
|
readFragment(artifact, fragmentRef) {
|
|
682
696
|
const entityKey = fragmentRef[FragmentRefKey];
|
|
683
|
-
if (!this.#storage[entityKey]) return
|
|
684
|
-
|
|
685
|
-
|
|
697
|
+
if (!this.#storage[entityKey]) return {
|
|
698
|
+
data: null,
|
|
699
|
+
stale: false
|
|
700
|
+
};
|
|
701
|
+
let stale = false;
|
|
702
|
+
const { data, partial } = denormalize(artifact.selections, this.#storage, { [EntityLinkKey]: entityKey }, {}, (storageKey, fieldKey) => {
|
|
703
|
+
if (this.#stale.has(storageKey) || this.#stale.has(makeDependencyKey(storageKey, fieldKey))) stale = true;
|
|
704
|
+
});
|
|
705
|
+
if (partial) return {
|
|
706
|
+
data: null,
|
|
707
|
+
stale: false
|
|
708
|
+
};
|
|
686
709
|
const key = makeMemoKey("fragment", artifact.name, entityKey);
|
|
687
710
|
const prev = this.#memo.get(key);
|
|
688
711
|
const result = prev === void 0 ? data : replaceEqualDeep(prev, data);
|
|
689
712
|
this.#memo.set(key, result);
|
|
690
|
-
return
|
|
713
|
+
return {
|
|
714
|
+
data: result,
|
|
715
|
+
stale
|
|
716
|
+
};
|
|
691
717
|
}
|
|
692
718
|
subscribeFragment(artifact, fragmentRef, listener) {
|
|
693
719
|
const entityKey = fragmentRef[FragmentRefKey];
|
|
@@ -700,17 +726,25 @@ var Cache = class {
|
|
|
700
726
|
}
|
|
701
727
|
readFragments(artifact, fragmentRefs) {
|
|
702
728
|
const results = [];
|
|
729
|
+
let stale = false;
|
|
703
730
|
for (const ref of fragmentRefs) {
|
|
704
|
-
const
|
|
705
|
-
if (data === null) return
|
|
706
|
-
|
|
731
|
+
const result = this.readFragment(artifact, ref);
|
|
732
|
+
if (result.data === null) return {
|
|
733
|
+
data: null,
|
|
734
|
+
stale: false
|
|
735
|
+
};
|
|
736
|
+
if (result.stale) stale = true;
|
|
737
|
+
results.push(result.data);
|
|
707
738
|
}
|
|
708
739
|
const entityKeys = fragmentRefs.map((ref) => ref[FragmentRefKey]);
|
|
709
740
|
const key = makeMemoKey("fragments", artifact.name, entityKeys.join(","));
|
|
710
741
|
const prev = this.#memo.get(key);
|
|
711
742
|
const result = prev === void 0 ? results : replaceEqualDeep(prev, results);
|
|
712
743
|
this.#memo.set(key, result);
|
|
713
|
-
return
|
|
744
|
+
return {
|
|
745
|
+
data: result,
|
|
746
|
+
stale
|
|
747
|
+
};
|
|
714
748
|
}
|
|
715
749
|
subscribeFragments(artifact, fragmentRefs, listener) {
|
|
716
750
|
const dependencies = /* @__PURE__ */ new Set();
|
|
@@ -730,48 +764,38 @@ var Cache = class {
|
|
|
730
764
|
const subscriptions = /* @__PURE__ */ new Set();
|
|
731
765
|
for (const target of targets) if (target.__typename === "Query") if ("field" in target) {
|
|
732
766
|
const fieldKey = makeFieldKeyFromArgs(target.field, target.args);
|
|
733
|
-
|
|
767
|
+
const depKey = makeDependencyKey(RootFieldKey, fieldKey);
|
|
768
|
+
this.#stale.add(depKey);
|
|
734
769
|
this.#collectSubscriptions(RootFieldKey, fieldKey, subscriptions);
|
|
735
770
|
} else {
|
|
736
|
-
this.#
|
|
771
|
+
this.#stale.add(RootFieldKey);
|
|
737
772
|
this.#collectSubscriptions(RootFieldKey, void 0, subscriptions);
|
|
738
773
|
}
|
|
739
774
|
else if ("id" in target) {
|
|
740
775
|
const entityKey = resolveEntityKey(target.__typename, target.id, this.#schemaMeta.entities[target.__typename]?.keyFields);
|
|
741
776
|
if ("field" in target) {
|
|
742
777
|
const fieldKey = makeFieldKeyFromArgs(target.field, target.args);
|
|
743
|
-
|
|
778
|
+
this.#stale.add(makeDependencyKey(entityKey, fieldKey));
|
|
744
779
|
this.#collectSubscriptions(entityKey, fieldKey, subscriptions);
|
|
745
780
|
} else {
|
|
746
|
-
|
|
781
|
+
this.#stale.add(entityKey);
|
|
747
782
|
this.#collectSubscriptions(entityKey, void 0, subscriptions);
|
|
748
783
|
}
|
|
749
|
-
this.#collectLinkedEntitySubscriptions((linkedEntityKey) => linkedEntityKey === entityKey, subscriptions);
|
|
750
784
|
} else {
|
|
751
785
|
const prefix = `${target.__typename}:`;
|
|
752
786
|
for (const key of Object.keys(this.#storage)) if (key.startsWith(prefix)) {
|
|
753
787
|
const entityKey = key;
|
|
754
788
|
if ("field" in target) {
|
|
755
789
|
const fieldKey = makeFieldKeyFromArgs(target.field, target.args);
|
|
756
|
-
|
|
790
|
+
this.#stale.add(makeDependencyKey(entityKey, fieldKey));
|
|
757
791
|
this.#collectSubscriptions(entityKey, fieldKey, subscriptions);
|
|
758
792
|
} else {
|
|
759
|
-
|
|
793
|
+
this.#stale.add(entityKey);
|
|
760
794
|
this.#collectSubscriptions(entityKey, void 0, subscriptions);
|
|
761
795
|
}
|
|
762
796
|
}
|
|
763
|
-
this.#collectLinkedEntitySubscriptions((linkedEntityKey) => linkedEntityKey.startsWith(prefix), subscriptions);
|
|
764
797
|
}
|
|
765
|
-
for (const subscription of subscriptions) subscription.listener(
|
|
766
|
-
}
|
|
767
|
-
#collectLinkedEntitySubscriptions(matcher, out) {
|
|
768
|
-
for (const [storageKey, fields] of Object.entries(this.#storage)) for (const [fieldKey, value] of Object.entries(fields)) if (this.#containsEntityLink(value, matcher)) this.#collectSubscriptions(storageKey, fieldKey, out);
|
|
769
|
-
}
|
|
770
|
-
#containsEntityLink(value, matcher) {
|
|
771
|
-
if (isEntityLink(value)) return matcher(value[EntityLinkKey]);
|
|
772
|
-
if (Array.isArray(value)) return value.some((item) => this.#containsEntityLink(item, matcher));
|
|
773
|
-
if (value && typeof value === "object") return Object.values(value).some((item) => this.#containsEntityLink(item, matcher));
|
|
774
|
-
return false;
|
|
798
|
+
for (const subscription of subscriptions) subscription.listener();
|
|
775
799
|
}
|
|
776
800
|
#collectSubscriptions(storageKey, fieldKey, out) {
|
|
777
801
|
if (fieldKey === void 0) {
|
|
@@ -825,6 +849,7 @@ var Cache = class {
|
|
|
825
849
|
this.#storage = { [RootFieldKey]: {} };
|
|
826
850
|
this.#subscriptions.clear();
|
|
827
851
|
this.#memo.clear();
|
|
852
|
+
this.#stale.clear();
|
|
828
853
|
}
|
|
829
854
|
};
|
|
830
855
|
|
|
@@ -864,27 +889,16 @@ const cacheExchange = (options = {}) => {
|
|
|
864
889
|
});
|
|
865
890
|
if (isFragmentRefArray(fragmentRef)) {
|
|
866
891
|
const trigger = require_make.makeSubject();
|
|
867
|
-
let hasData = false;
|
|
868
892
|
const teardown$ = require_make.pipe(ops$, require_make.filter((operation) => operation.variant === "teardown" && operation.key === op.key), require_make.tap(() => trigger.complete()));
|
|
869
893
|
return require_make.pipe(require_make.merge(require_make.fromValue(void 0), trigger.source), require_make.switchMap(() => require_make.fromSubscription(() => cache.readFragments(op.artifact, fragmentRef), () => cache.subscribeFragments(op.artifact, fragmentRef, async () => {
|
|
870
894
|
await Promise.resolve();
|
|
871
895
|
trigger.next();
|
|
872
|
-
}))), require_make.takeUntil(teardown$), require_make.
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
errors: []
|
|
879
|
-
});
|
|
880
|
-
}
|
|
881
|
-
if (hasData) return empty();
|
|
882
|
-
return require_make.fromValue({
|
|
883
|
-
operation: op,
|
|
884
|
-
data,
|
|
885
|
-
errors: []
|
|
886
|
-
});
|
|
887
|
-
}));
|
|
896
|
+
}))), require_make.takeUntil(teardown$), require_make.map(({ data, stale }) => ({
|
|
897
|
+
operation: op,
|
|
898
|
+
data,
|
|
899
|
+
...stale && { metadata: { cache: { stale: true } } },
|
|
900
|
+
errors: []
|
|
901
|
+
})));
|
|
888
902
|
}
|
|
889
903
|
if (!isFragmentRef(fragmentRef)) return require_make.fromValue({
|
|
890
904
|
operation: op,
|
|
@@ -892,27 +906,16 @@ const cacheExchange = (options = {}) => {
|
|
|
892
906
|
errors: []
|
|
893
907
|
});
|
|
894
908
|
const trigger = require_make.makeSubject();
|
|
895
|
-
let hasData = false;
|
|
896
909
|
const teardown$ = require_make.pipe(ops$, require_make.filter((operation) => operation.variant === "teardown" && operation.key === op.key), require_make.tap(() => trigger.complete()));
|
|
897
910
|
return require_make.pipe(require_make.merge(require_make.fromValue(void 0), trigger.source), require_make.switchMap(() => require_make.fromSubscription(() => cache.readFragment(op.artifact, fragmentRef), () => cache.subscribeFragment(op.artifact, fragmentRef, async () => {
|
|
898
911
|
await Promise.resolve();
|
|
899
912
|
trigger.next();
|
|
900
|
-
}))), require_make.takeUntil(teardown$), require_make.
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
errors: []
|
|
907
|
-
});
|
|
908
|
-
}
|
|
909
|
-
if (hasData) return empty();
|
|
910
|
-
return require_make.fromValue({
|
|
911
|
-
operation: op,
|
|
912
|
-
data,
|
|
913
|
-
errors: []
|
|
914
|
-
});
|
|
915
|
-
}));
|
|
913
|
+
}))), require_make.takeUntil(teardown$), require_make.map(({ data, stale }) => ({
|
|
914
|
+
operation: op,
|
|
915
|
+
data,
|
|
916
|
+
...stale && { metadata: { cache: { stale: true } } },
|
|
917
|
+
errors: []
|
|
918
|
+
})));
|
|
916
919
|
}));
|
|
917
920
|
const nonCache$ = require_make.pipe(ops$, require_make.filter((op) => op.variant === "request" && (op.artifact.kind === "mutation" || op.artifact.kind === "subscription" || op.artifact.kind === "query" && fetchPolicy === "network-only")));
|
|
918
921
|
const query$ = require_make.pipe(ops$, require_make.filter((op) => op.variant === "request" && op.artifact.kind === "query" && fetchPolicy !== "network-only"), require_make.share());
|
|
@@ -920,30 +923,31 @@ const cacheExchange = (options = {}) => {
|
|
|
920
923
|
return require_make.merge(fragment$, require_make.pipe(query$, require_make.mergeMap((op) => {
|
|
921
924
|
const trigger = require_make.makeSubject();
|
|
922
925
|
let hasData = false;
|
|
923
|
-
let invalidated = false;
|
|
924
926
|
const teardown$ = require_make.pipe(ops$, require_make.filter((operation) => operation.variant === "teardown" && operation.key === op.key), require_make.tap(() => trigger.complete()));
|
|
925
|
-
return require_make.pipe(require_make.merge(require_make.fromValue(void 0), trigger.source), require_make.switchMap(() => require_make.fromSubscription(() => cache.readQuery(op.artifact, op.variables), () => cache.subscribeQuery(op.artifact, op.variables, async (
|
|
926
|
-
if (event === "invalidate") invalidated = true;
|
|
927
|
+
return require_make.pipe(require_make.merge(require_make.fromValue(void 0), trigger.source), require_make.switchMap(() => require_make.fromSubscription(() => cache.readQuery(op.artifact, op.variables), () => cache.subscribeQuery(op.artifact, op.variables, async () => {
|
|
927
928
|
await Promise.resolve();
|
|
928
929
|
trigger.next();
|
|
929
|
-
}))), require_make.takeUntil(teardown$), require_make.mergeMap((data) => {
|
|
930
|
-
if (data !== null) {
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
930
|
+
}))), require_make.takeUntil(teardown$), require_make.mergeMap(({ data, stale }) => {
|
|
931
|
+
if (data !== null && !stale) {
|
|
932
|
+
hasData = true;
|
|
933
|
+
return require_make.fromValue({
|
|
934
|
+
operation: op,
|
|
935
|
+
data,
|
|
936
|
+
errors: []
|
|
937
|
+
});
|
|
938
|
+
}
|
|
939
|
+
if (data !== null && stale) {
|
|
936
940
|
hasData = true;
|
|
937
|
-
|
|
941
|
+
refetch$.next(op);
|
|
938
942
|
return require_make.fromValue({
|
|
939
943
|
operation: op,
|
|
940
944
|
data,
|
|
945
|
+
metadata: { cache: { stale: true } },
|
|
941
946
|
errors: []
|
|
942
947
|
});
|
|
943
948
|
}
|
|
944
949
|
if (hasData) {
|
|
945
|
-
|
|
946
|
-
invalidated = false;
|
|
950
|
+
refetch$.next(op);
|
|
947
951
|
return empty();
|
|
948
952
|
}
|
|
949
953
|
if (fetchPolicy === "cache-only") return require_make.fromValue({
|
|
@@ -954,8 +958,8 @@ const cacheExchange = (options = {}) => {
|
|
|
954
958
|
return empty();
|
|
955
959
|
}));
|
|
956
960
|
}), require_make.filter(() => fetchPolicy === "cache-only" || fetchPolicy === "cache-and-network" || fetchPolicy === "cache-first")), require_make.pipe(require_make.merge(nonCache$, require_make.pipe(query$, require_make.filter((op) => {
|
|
957
|
-
const
|
|
958
|
-
return fetchPolicy === "cache-and-network" ||
|
|
961
|
+
const { data } = cache.readQuery(op.artifact, op.variables);
|
|
962
|
+
return fetchPolicy === "cache-and-network" || data === null;
|
|
959
963
|
})), require_make.pipe(ops$, require_make.filter((op) => op.variant === "teardown")), refetch$.source), forward, require_make.tap((result) => {
|
|
960
964
|
if (result.operation.variant === "request" && result.data) cache.writeQuery(result.operation.artifact, result.operation.variables, result.data);
|
|
961
965
|
}), require_make.filter((result) => result.operation.variant !== "request" || result.operation.artifact.kind !== "query" || fetchPolicy === "network-only" || !!(result.errors && result.errors.length > 0))));
|
package/dist/index.d.cts
CHANGED
|
@@ -116,6 +116,7 @@ declare const createClient: <T extends SchemaMeta$1>(config: ClientOptions<T>) =
|
|
|
116
116
|
//#endregion
|
|
117
117
|
//#region src/exchange.d.ts
|
|
118
118
|
interface OperationMetadataMap {}
|
|
119
|
+
interface OperationResultMetadataMap {}
|
|
119
120
|
type OperationMetadata = { [K in keyof OperationMetadataMap]?: OperationMetadataMap[K] } & Record<string, unknown>;
|
|
120
121
|
type BaseOperation = {
|
|
121
122
|
key: string;
|
|
@@ -135,7 +136,7 @@ type OperationResult = {
|
|
|
135
136
|
data?: unknown;
|
|
136
137
|
errors?: readonly OperationError[];
|
|
137
138
|
extensions?: Record<string, unknown>;
|
|
138
|
-
|
|
139
|
+
metadata?: OperationResultMetadataMap & Record<string, unknown>;
|
|
139
140
|
};
|
|
140
141
|
type ExchangeInput<TMeta extends SchemaMeta$1 = SchemaMeta$1> = {
|
|
141
142
|
forward: ExchangeIO;
|
|
@@ -243,6 +244,11 @@ declare module '@mearie/core' {
|
|
|
243
244
|
interface ExchangeExtensionMap {
|
|
244
245
|
cache: CacheOperations;
|
|
245
246
|
}
|
|
247
|
+
interface OperationResultMetadataMap {
|
|
248
|
+
cache?: {
|
|
249
|
+
stale: boolean;
|
|
250
|
+
};
|
|
251
|
+
}
|
|
246
252
|
}
|
|
247
253
|
type CacheOptions = {
|
|
248
254
|
fetchPolicy?: 'cache-first' | 'cache-and-network' | 'network-only' | 'cache-only';
|
|
@@ -345,4 +351,4 @@ declare class RequiredFieldError extends Error {
|
|
|
345
351
|
*/
|
|
346
352
|
declare const stringify: (value: unknown) => string;
|
|
347
353
|
//#endregion
|
|
348
|
-
export { AggregatedError, type Artifact, type ArtifactKind, type CacheOptions, type CacheSnapshot, Client, type ClientOptions, type DataOf, type Exchange, ExchangeError, type ExchangeErrorExtensionsMap, type ExchangeExtensionMap, type ExchangeIO, type ExchangeResult, type FragmentOptions, type FragmentRefs, GraphQLError, type HttpOptions, type MutationOptions, type Operation, type OperationError, type OperationMetadata, type OperationMetadataMap, type OperationResult, type QueryOptions, type RequiredAction, RequiredFieldError, type RetryOptions, type SchemaMeta, type SubscriptionClient, type SubscriptionExchangeOptions, type SubscriptionOptions, type VariablesOf, cacheExchange, createClient, dedupExchange, fragmentExchange, httpExchange, isAggregatedError, isExchangeError, isGraphQLError, requiredExchange, retryExchange, stringify, subscriptionExchange };
|
|
354
|
+
export { AggregatedError, type Artifact, type ArtifactKind, type CacheOptions, type CacheSnapshot, Client, type ClientOptions, type DataOf, type Exchange, ExchangeError, type ExchangeErrorExtensionsMap, type ExchangeExtensionMap, type ExchangeIO, type ExchangeResult, type FragmentOptions, type FragmentRefs, GraphQLError, type HttpOptions, type MutationOptions, type Operation, type OperationError, type OperationMetadata, type OperationMetadataMap, type OperationResult, type OperationResultMetadataMap, type QueryOptions, type RequiredAction, RequiredFieldError, type RetryOptions, type SchemaMeta, type SubscriptionClient, type SubscriptionExchangeOptions, type SubscriptionOptions, type VariablesOf, cacheExchange, createClient, dedupExchange, fragmentExchange, httpExchange, isAggregatedError, isExchangeError, isGraphQLError, requiredExchange, retryExchange, stringify, subscriptionExchange };
|
package/dist/index.d.mts
CHANGED
|
@@ -116,6 +116,7 @@ declare const createClient: <T extends SchemaMeta$1>(config: ClientOptions<T>) =
|
|
|
116
116
|
//#endregion
|
|
117
117
|
//#region src/exchange.d.ts
|
|
118
118
|
interface OperationMetadataMap {}
|
|
119
|
+
interface OperationResultMetadataMap {}
|
|
119
120
|
type OperationMetadata = { [K in keyof OperationMetadataMap]?: OperationMetadataMap[K] } & Record<string, unknown>;
|
|
120
121
|
type BaseOperation = {
|
|
121
122
|
key: string;
|
|
@@ -135,7 +136,7 @@ type OperationResult = {
|
|
|
135
136
|
data?: unknown;
|
|
136
137
|
errors?: readonly OperationError[];
|
|
137
138
|
extensions?: Record<string, unknown>;
|
|
138
|
-
|
|
139
|
+
metadata?: OperationResultMetadataMap & Record<string, unknown>;
|
|
139
140
|
};
|
|
140
141
|
type ExchangeInput<TMeta extends SchemaMeta$1 = SchemaMeta$1> = {
|
|
141
142
|
forward: ExchangeIO;
|
|
@@ -243,6 +244,11 @@ declare module '@mearie/core' {
|
|
|
243
244
|
interface ExchangeExtensionMap {
|
|
244
245
|
cache: CacheOperations;
|
|
245
246
|
}
|
|
247
|
+
interface OperationResultMetadataMap {
|
|
248
|
+
cache?: {
|
|
249
|
+
stale: boolean;
|
|
250
|
+
};
|
|
251
|
+
}
|
|
246
252
|
}
|
|
247
253
|
type CacheOptions = {
|
|
248
254
|
fetchPolicy?: 'cache-first' | 'cache-and-network' | 'network-only' | 'cache-only';
|
|
@@ -345,4 +351,4 @@ declare class RequiredFieldError extends Error {
|
|
|
345
351
|
*/
|
|
346
352
|
declare const stringify: (value: unknown) => string;
|
|
347
353
|
//#endregion
|
|
348
|
-
export { AggregatedError, type Artifact, type ArtifactKind, type CacheOptions, type CacheSnapshot, Client, type ClientOptions, type DataOf, type Exchange, ExchangeError, type ExchangeErrorExtensionsMap, type ExchangeExtensionMap, type ExchangeIO, type ExchangeResult, type FragmentOptions, type FragmentRefs, GraphQLError, type HttpOptions, type MutationOptions, type Operation, type OperationError, type OperationMetadata, type OperationMetadataMap, type OperationResult, type QueryOptions, type RequiredAction, RequiredFieldError, type RetryOptions, type SchemaMeta, type SubscriptionClient, type SubscriptionExchangeOptions, type SubscriptionOptions, type VariablesOf, cacheExchange, createClient, dedupExchange, fragmentExchange, httpExchange, isAggregatedError, isExchangeError, isGraphQLError, requiredExchange, retryExchange, stringify, subscriptionExchange };
|
|
354
|
+
export { AggregatedError, type Artifact, type ArtifactKind, type CacheOptions, type CacheSnapshot, Client, type ClientOptions, type DataOf, type Exchange, ExchangeError, type ExchangeErrorExtensionsMap, type ExchangeExtensionMap, type ExchangeIO, type ExchangeResult, type FragmentOptions, type FragmentRefs, GraphQLError, type HttpOptions, type MutationOptions, type Operation, type OperationError, type OperationMetadata, type OperationMetadataMap, type OperationResult, type OperationResultMetadataMap, type QueryOptions, type RequiredAction, RequiredFieldError, type RetryOptions, type SchemaMeta, type SubscriptionClient, type SubscriptionExchangeOptions, type SubscriptionOptions, type VariablesOf, cacheExchange, createClient, dedupExchange, fragmentExchange, httpExchange, isAggregatedError, isExchangeError, isGraphQLError, requiredExchange, retryExchange, stringify, subscriptionExchange };
|
package/dist/index.mjs
CHANGED
|
@@ -593,8 +593,10 @@ const denormalize = (selections, storage, value, variables, accessor) => {
|
|
|
593
593
|
const value = selection.selections ? denormalizeField(null, selection.selections, fieldValue) : fieldValue;
|
|
594
594
|
if (name in fields) mergeFields(fields, { [name]: value });
|
|
595
595
|
else fields[name] = value;
|
|
596
|
-
} else if (selection.kind === "FragmentSpread") if (storageKey !== null && storageKey !== RootFieldKey)
|
|
597
|
-
|
|
596
|
+
} else if (selection.kind === "FragmentSpread") if (storageKey !== null && storageKey !== RootFieldKey) {
|
|
597
|
+
fields[FragmentRefKey] = storageKey;
|
|
598
|
+
if (accessor) denormalize(selection.selections, storage, { [EntityLinkKey]: storageKey }, variables, accessor);
|
|
599
|
+
} else mergeFields(fields, denormalizeField(storageKey, selection.selections, value));
|
|
598
600
|
else if (selection.kind === "InlineFragment" && selection.on === data[typenameFieldKey]) mergeFields(fields, denormalizeField(storageKey, selection.selections, value));
|
|
599
601
|
return fields;
|
|
600
602
|
};
|
|
@@ -615,6 +617,7 @@ var Cache = class {
|
|
|
615
617
|
#storage = { [RootFieldKey]: {} };
|
|
616
618
|
#subscriptions = /* @__PURE__ */ new Map();
|
|
617
619
|
#memo = /* @__PURE__ */ new Map();
|
|
620
|
+
#stale = /* @__PURE__ */ new Set();
|
|
618
621
|
constructor(schemaMetadata) {
|
|
619
622
|
this.#schemaMeta = schemaMetadata;
|
|
620
623
|
}
|
|
@@ -627,17 +630,19 @@ var Cache = class {
|
|
|
627
630
|
writeQuery(artifact, variables, data) {
|
|
628
631
|
const dependencies = /* @__PURE__ */ new Set();
|
|
629
632
|
const subscriptions = /* @__PURE__ */ new Set();
|
|
633
|
+
const entityStaleCleared = /* @__PURE__ */ new Set();
|
|
630
634
|
normalize(this.#schemaMeta, artifact.selections, this.#storage, data, variables, (storageKey, fieldKey, oldValue, newValue) => {
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
+
const depKey = makeDependencyKey(storageKey, fieldKey);
|
|
636
|
+
if (this.#stale.delete(depKey)) dependencies.add(depKey);
|
|
637
|
+
if (!entityStaleCleared.has(storageKey) && this.#stale.delete(storageKey)) entityStaleCleared.add(storageKey);
|
|
638
|
+
if (oldValue !== newValue) dependencies.add(depKey);
|
|
635
639
|
});
|
|
640
|
+
for (const entityKey of entityStaleCleared) this.#collectSubscriptions(entityKey, void 0, subscriptions);
|
|
636
641
|
for (const dependency of dependencies) {
|
|
637
642
|
const ss = this.#subscriptions.get(dependency);
|
|
638
643
|
if (ss) for (const s of ss) subscriptions.add(s);
|
|
639
644
|
}
|
|
640
|
-
for (const subscription of subscriptions) subscription.listener(
|
|
645
|
+
for (const subscription of subscriptions) subscription.listener();
|
|
641
646
|
}
|
|
642
647
|
/**
|
|
643
648
|
* Reads a query result from the cache, denormalizing entities if available.
|
|
@@ -647,13 +652,22 @@ var Cache = class {
|
|
|
647
652
|
* @returns Denormalized query result or null if not found.
|
|
648
653
|
*/
|
|
649
654
|
readQuery(artifact, variables) {
|
|
650
|
-
|
|
651
|
-
|
|
655
|
+
let stale = false;
|
|
656
|
+
const { data, partial } = denormalize(artifact.selections, this.#storage, this.#storage[RootFieldKey], variables, (storageKey, fieldKey) => {
|
|
657
|
+
if (this.#stale.has(storageKey) || this.#stale.has(makeDependencyKey(storageKey, fieldKey))) stale = true;
|
|
658
|
+
});
|
|
659
|
+
if (partial) return {
|
|
660
|
+
data: null,
|
|
661
|
+
stale: false
|
|
662
|
+
};
|
|
652
663
|
const key = makeMemoKey("query", artifact.name, stringify(variables));
|
|
653
664
|
const prev = this.#memo.get(key);
|
|
654
665
|
const result = prev === void 0 ? data : replaceEqualDeep(prev, data);
|
|
655
666
|
this.#memo.set(key, result);
|
|
656
|
-
return
|
|
667
|
+
return {
|
|
668
|
+
data: result,
|
|
669
|
+
stale
|
|
670
|
+
};
|
|
657
671
|
}
|
|
658
672
|
/**
|
|
659
673
|
* Subscribes to cache invalidations for a specific query.
|
|
@@ -679,14 +693,26 @@ var Cache = class {
|
|
|
679
693
|
*/
|
|
680
694
|
readFragment(artifact, fragmentRef) {
|
|
681
695
|
const entityKey = fragmentRef[FragmentRefKey];
|
|
682
|
-
if (!this.#storage[entityKey]) return
|
|
683
|
-
|
|
684
|
-
|
|
696
|
+
if (!this.#storage[entityKey]) return {
|
|
697
|
+
data: null,
|
|
698
|
+
stale: false
|
|
699
|
+
};
|
|
700
|
+
let stale = false;
|
|
701
|
+
const { data, partial } = denormalize(artifact.selections, this.#storage, { [EntityLinkKey]: entityKey }, {}, (storageKey, fieldKey) => {
|
|
702
|
+
if (this.#stale.has(storageKey) || this.#stale.has(makeDependencyKey(storageKey, fieldKey))) stale = true;
|
|
703
|
+
});
|
|
704
|
+
if (partial) return {
|
|
705
|
+
data: null,
|
|
706
|
+
stale: false
|
|
707
|
+
};
|
|
685
708
|
const key = makeMemoKey("fragment", artifact.name, entityKey);
|
|
686
709
|
const prev = this.#memo.get(key);
|
|
687
710
|
const result = prev === void 0 ? data : replaceEqualDeep(prev, data);
|
|
688
711
|
this.#memo.set(key, result);
|
|
689
|
-
return
|
|
712
|
+
return {
|
|
713
|
+
data: result,
|
|
714
|
+
stale
|
|
715
|
+
};
|
|
690
716
|
}
|
|
691
717
|
subscribeFragment(artifact, fragmentRef, listener) {
|
|
692
718
|
const entityKey = fragmentRef[FragmentRefKey];
|
|
@@ -699,17 +725,25 @@ var Cache = class {
|
|
|
699
725
|
}
|
|
700
726
|
readFragments(artifact, fragmentRefs) {
|
|
701
727
|
const results = [];
|
|
728
|
+
let stale = false;
|
|
702
729
|
for (const ref of fragmentRefs) {
|
|
703
|
-
const
|
|
704
|
-
if (data === null) return
|
|
705
|
-
|
|
730
|
+
const result = this.readFragment(artifact, ref);
|
|
731
|
+
if (result.data === null) return {
|
|
732
|
+
data: null,
|
|
733
|
+
stale: false
|
|
734
|
+
};
|
|
735
|
+
if (result.stale) stale = true;
|
|
736
|
+
results.push(result.data);
|
|
706
737
|
}
|
|
707
738
|
const entityKeys = fragmentRefs.map((ref) => ref[FragmentRefKey]);
|
|
708
739
|
const key = makeMemoKey("fragments", artifact.name, entityKeys.join(","));
|
|
709
740
|
const prev = this.#memo.get(key);
|
|
710
741
|
const result = prev === void 0 ? results : replaceEqualDeep(prev, results);
|
|
711
742
|
this.#memo.set(key, result);
|
|
712
|
-
return
|
|
743
|
+
return {
|
|
744
|
+
data: result,
|
|
745
|
+
stale
|
|
746
|
+
};
|
|
713
747
|
}
|
|
714
748
|
subscribeFragments(artifact, fragmentRefs, listener) {
|
|
715
749
|
const dependencies = /* @__PURE__ */ new Set();
|
|
@@ -729,48 +763,38 @@ var Cache = class {
|
|
|
729
763
|
const subscriptions = /* @__PURE__ */ new Set();
|
|
730
764
|
for (const target of targets) if (target.__typename === "Query") if ("field" in target) {
|
|
731
765
|
const fieldKey = makeFieldKeyFromArgs(target.field, target.args);
|
|
732
|
-
|
|
766
|
+
const depKey = makeDependencyKey(RootFieldKey, fieldKey);
|
|
767
|
+
this.#stale.add(depKey);
|
|
733
768
|
this.#collectSubscriptions(RootFieldKey, fieldKey, subscriptions);
|
|
734
769
|
} else {
|
|
735
|
-
this.#
|
|
770
|
+
this.#stale.add(RootFieldKey);
|
|
736
771
|
this.#collectSubscriptions(RootFieldKey, void 0, subscriptions);
|
|
737
772
|
}
|
|
738
773
|
else if ("id" in target) {
|
|
739
774
|
const entityKey = resolveEntityKey(target.__typename, target.id, this.#schemaMeta.entities[target.__typename]?.keyFields);
|
|
740
775
|
if ("field" in target) {
|
|
741
776
|
const fieldKey = makeFieldKeyFromArgs(target.field, target.args);
|
|
742
|
-
|
|
777
|
+
this.#stale.add(makeDependencyKey(entityKey, fieldKey));
|
|
743
778
|
this.#collectSubscriptions(entityKey, fieldKey, subscriptions);
|
|
744
779
|
} else {
|
|
745
|
-
|
|
780
|
+
this.#stale.add(entityKey);
|
|
746
781
|
this.#collectSubscriptions(entityKey, void 0, subscriptions);
|
|
747
782
|
}
|
|
748
|
-
this.#collectLinkedEntitySubscriptions((linkedEntityKey) => linkedEntityKey === entityKey, subscriptions);
|
|
749
783
|
} else {
|
|
750
784
|
const prefix = `${target.__typename}:`;
|
|
751
785
|
for (const key of Object.keys(this.#storage)) if (key.startsWith(prefix)) {
|
|
752
786
|
const entityKey = key;
|
|
753
787
|
if ("field" in target) {
|
|
754
788
|
const fieldKey = makeFieldKeyFromArgs(target.field, target.args);
|
|
755
|
-
|
|
789
|
+
this.#stale.add(makeDependencyKey(entityKey, fieldKey));
|
|
756
790
|
this.#collectSubscriptions(entityKey, fieldKey, subscriptions);
|
|
757
791
|
} else {
|
|
758
|
-
|
|
792
|
+
this.#stale.add(entityKey);
|
|
759
793
|
this.#collectSubscriptions(entityKey, void 0, subscriptions);
|
|
760
794
|
}
|
|
761
795
|
}
|
|
762
|
-
this.#collectLinkedEntitySubscriptions((linkedEntityKey) => linkedEntityKey.startsWith(prefix), subscriptions);
|
|
763
796
|
}
|
|
764
|
-
for (const subscription of subscriptions) subscription.listener(
|
|
765
|
-
}
|
|
766
|
-
#collectLinkedEntitySubscriptions(matcher, out) {
|
|
767
|
-
for (const [storageKey, fields] of Object.entries(this.#storage)) for (const [fieldKey, value] of Object.entries(fields)) if (this.#containsEntityLink(value, matcher)) this.#collectSubscriptions(storageKey, fieldKey, out);
|
|
768
|
-
}
|
|
769
|
-
#containsEntityLink(value, matcher) {
|
|
770
|
-
if (isEntityLink(value)) return matcher(value[EntityLinkKey]);
|
|
771
|
-
if (Array.isArray(value)) return value.some((item) => this.#containsEntityLink(item, matcher));
|
|
772
|
-
if (value && typeof value === "object") return Object.values(value).some((item) => this.#containsEntityLink(item, matcher));
|
|
773
|
-
return false;
|
|
797
|
+
for (const subscription of subscriptions) subscription.listener();
|
|
774
798
|
}
|
|
775
799
|
#collectSubscriptions(storageKey, fieldKey, out) {
|
|
776
800
|
if (fieldKey === void 0) {
|
|
@@ -824,6 +848,7 @@ var Cache = class {
|
|
|
824
848
|
this.#storage = { [RootFieldKey]: {} };
|
|
825
849
|
this.#subscriptions.clear();
|
|
826
850
|
this.#memo.clear();
|
|
851
|
+
this.#stale.clear();
|
|
827
852
|
}
|
|
828
853
|
};
|
|
829
854
|
|
|
@@ -863,27 +888,16 @@ const cacheExchange = (options = {}) => {
|
|
|
863
888
|
});
|
|
864
889
|
if (isFragmentRefArray(fragmentRef)) {
|
|
865
890
|
const trigger = makeSubject();
|
|
866
|
-
let hasData = false;
|
|
867
891
|
const teardown$ = pipe(ops$, filter((operation) => operation.variant === "teardown" && operation.key === op.key), tap(() => trigger.complete()));
|
|
868
892
|
return pipe(merge(fromValue(void 0), trigger.source), switchMap(() => fromSubscription(() => cache.readFragments(op.artifact, fragmentRef), () => cache.subscribeFragments(op.artifact, fragmentRef, async () => {
|
|
869
893
|
await Promise.resolve();
|
|
870
894
|
trigger.next();
|
|
871
|
-
}))), takeUntil(teardown$),
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
errors: []
|
|
878
|
-
});
|
|
879
|
-
}
|
|
880
|
-
if (hasData) return empty();
|
|
881
|
-
return fromValue({
|
|
882
|
-
operation: op,
|
|
883
|
-
data,
|
|
884
|
-
errors: []
|
|
885
|
-
});
|
|
886
|
-
}));
|
|
895
|
+
}))), takeUntil(teardown$), map(({ data, stale }) => ({
|
|
896
|
+
operation: op,
|
|
897
|
+
data,
|
|
898
|
+
...stale && { metadata: { cache: { stale: true } } },
|
|
899
|
+
errors: []
|
|
900
|
+
})));
|
|
887
901
|
}
|
|
888
902
|
if (!isFragmentRef(fragmentRef)) return fromValue({
|
|
889
903
|
operation: op,
|
|
@@ -891,27 +905,16 @@ const cacheExchange = (options = {}) => {
|
|
|
891
905
|
errors: []
|
|
892
906
|
});
|
|
893
907
|
const trigger = makeSubject();
|
|
894
|
-
let hasData = false;
|
|
895
908
|
const teardown$ = pipe(ops$, filter((operation) => operation.variant === "teardown" && operation.key === op.key), tap(() => trigger.complete()));
|
|
896
909
|
return pipe(merge(fromValue(void 0), trigger.source), switchMap(() => fromSubscription(() => cache.readFragment(op.artifact, fragmentRef), () => cache.subscribeFragment(op.artifact, fragmentRef, async () => {
|
|
897
910
|
await Promise.resolve();
|
|
898
911
|
trigger.next();
|
|
899
|
-
}))), takeUntil(teardown$),
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
errors: []
|
|
906
|
-
});
|
|
907
|
-
}
|
|
908
|
-
if (hasData) return empty();
|
|
909
|
-
return fromValue({
|
|
910
|
-
operation: op,
|
|
911
|
-
data,
|
|
912
|
-
errors: []
|
|
913
|
-
});
|
|
914
|
-
}));
|
|
912
|
+
}))), takeUntil(teardown$), map(({ data, stale }) => ({
|
|
913
|
+
operation: op,
|
|
914
|
+
data,
|
|
915
|
+
...stale && { metadata: { cache: { stale: true } } },
|
|
916
|
+
errors: []
|
|
917
|
+
})));
|
|
915
918
|
}));
|
|
916
919
|
const nonCache$ = pipe(ops$, filter((op) => op.variant === "request" && (op.artifact.kind === "mutation" || op.artifact.kind === "subscription" || op.artifact.kind === "query" && fetchPolicy === "network-only")));
|
|
917
920
|
const query$ = pipe(ops$, filter((op) => op.variant === "request" && op.artifact.kind === "query" && fetchPolicy !== "network-only"), share());
|
|
@@ -919,30 +922,31 @@ const cacheExchange = (options = {}) => {
|
|
|
919
922
|
return merge(fragment$, pipe(query$, mergeMap((op) => {
|
|
920
923
|
const trigger = makeSubject();
|
|
921
924
|
let hasData = false;
|
|
922
|
-
let invalidated = false;
|
|
923
925
|
const teardown$ = pipe(ops$, filter((operation) => operation.variant === "teardown" && operation.key === op.key), tap(() => trigger.complete()));
|
|
924
|
-
return pipe(merge(fromValue(void 0), trigger.source), switchMap(() => fromSubscription(() => cache.readQuery(op.artifact, op.variables), () => cache.subscribeQuery(op.artifact, op.variables, async (
|
|
925
|
-
if (event === "invalidate") invalidated = true;
|
|
926
|
+
return pipe(merge(fromValue(void 0), trigger.source), switchMap(() => fromSubscription(() => cache.readQuery(op.artifact, op.variables), () => cache.subscribeQuery(op.artifact, op.variables, async () => {
|
|
926
927
|
await Promise.resolve();
|
|
927
928
|
trigger.next();
|
|
928
|
-
}))), takeUntil(teardown$), mergeMap((data) => {
|
|
929
|
-
if (data !== null) {
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
929
|
+
}))), takeUntil(teardown$), mergeMap(({ data, stale }) => {
|
|
930
|
+
if (data !== null && !stale) {
|
|
931
|
+
hasData = true;
|
|
932
|
+
return fromValue({
|
|
933
|
+
operation: op,
|
|
934
|
+
data,
|
|
935
|
+
errors: []
|
|
936
|
+
});
|
|
937
|
+
}
|
|
938
|
+
if (data !== null && stale) {
|
|
935
939
|
hasData = true;
|
|
936
|
-
|
|
940
|
+
refetch$.next(op);
|
|
937
941
|
return fromValue({
|
|
938
942
|
operation: op,
|
|
939
943
|
data,
|
|
944
|
+
metadata: { cache: { stale: true } },
|
|
940
945
|
errors: []
|
|
941
946
|
});
|
|
942
947
|
}
|
|
943
948
|
if (hasData) {
|
|
944
|
-
|
|
945
|
-
invalidated = false;
|
|
949
|
+
refetch$.next(op);
|
|
946
950
|
return empty();
|
|
947
951
|
}
|
|
948
952
|
if (fetchPolicy === "cache-only") return fromValue({
|
|
@@ -953,8 +957,8 @@ const cacheExchange = (options = {}) => {
|
|
|
953
957
|
return empty();
|
|
954
958
|
}));
|
|
955
959
|
}), filter(() => fetchPolicy === "cache-only" || fetchPolicy === "cache-and-network" || fetchPolicy === "cache-first")), pipe(merge(nonCache$, pipe(query$, filter((op) => {
|
|
956
|
-
const
|
|
957
|
-
return fetchPolicy === "cache-and-network" ||
|
|
960
|
+
const { data } = cache.readQuery(op.artifact, op.variables);
|
|
961
|
+
return fetchPolicy === "cache-and-network" || data === null;
|
|
958
962
|
})), pipe(ops$, filter((op) => op.variant === "teardown")), refetch$.source), forward, tap((result) => {
|
|
959
963
|
if (result.operation.variant === "request" && result.data) cache.writeQuery(result.operation.artifact, result.operation.variables, result.data);
|
|
960
964
|
}), filter((result) => result.operation.variant !== "request" || result.operation.artifact.kind !== "query" || fetchPolicy === "network-only" || !!(result.errors && result.errors.length > 0))));
|
package/package.json
CHANGED
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mearie/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Type-safe, zero-overhead GraphQL client",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"graphql",
|
|
7
7
|
"graphql-client",
|
|
8
8
|
"typescript",
|
|
9
|
+
"type-safe",
|
|
9
10
|
"codegen",
|
|
10
|
-
"cache"
|
|
11
|
+
"cache",
|
|
12
|
+
"normalized-cache",
|
|
13
|
+
"react",
|
|
14
|
+
"vue",
|
|
15
|
+
"svelte",
|
|
16
|
+
"solid",
|
|
17
|
+
"vite"
|
|
11
18
|
],
|
|
12
|
-
"homepage": "https://
|
|
19
|
+
"homepage": "https://mearie.dev/",
|
|
13
20
|
"bugs": {
|
|
14
21
|
"url": "https://github.com/devunt/mearie/issues"
|
|
15
22
|
},
|
|
@@ -55,7 +62,7 @@
|
|
|
55
62
|
"README.md"
|
|
56
63
|
],
|
|
57
64
|
"dependencies": {
|
|
58
|
-
"@mearie/shared": "0.2.
|
|
65
|
+
"@mearie/shared": "0.2.2"
|
|
59
66
|
},
|
|
60
67
|
"devDependencies": {
|
|
61
68
|
"tsdown": "^0.20.3",
|