@tanstack/preact-store 0.10.0 → 0.10.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.
@@ -1,8 +1,41 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const compat = require("preact/compat");
4
3
  const hooks = require("preact/hooks");
5
4
  const store = require("@tanstack/store");
5
+ function useSyncExternalStore(subscribe, getSnapshot) {
6
+ const value = getSnapshot();
7
+ const [{ _instance }, forceUpdate] = hooks.useState({
8
+ _instance: { _value: value, _getSnapshot: getSnapshot }
9
+ });
10
+ hooks.useLayoutEffect(() => {
11
+ _instance._value = value;
12
+ _instance._getSnapshot = getSnapshot;
13
+ if (didSnapshotChange(_instance)) {
14
+ forceUpdate({ _instance });
15
+ }
16
+ }, [subscribe, value, getSnapshot]);
17
+ hooks.useEffect(() => {
18
+ if (didSnapshotChange(_instance)) {
19
+ forceUpdate({ _instance });
20
+ }
21
+ return subscribe(() => {
22
+ if (didSnapshotChange(_instance)) {
23
+ forceUpdate({ _instance });
24
+ }
25
+ });
26
+ }, [subscribe]);
27
+ return value;
28
+ }
29
+ function didSnapshotChange(inst) {
30
+ const latestGetSnapshot = inst._getSnapshot;
31
+ const prevValue = inst._value;
32
+ try {
33
+ const nextValue = latestGetSnapshot();
34
+ return !Object.is(prevValue, nextValue);
35
+ } catch (_error) {
36
+ return true;
37
+ }
38
+ }
6
39
  function useSyncExternalStoreWithSelector(subscribe, getSnapshot, selector, isEqual) {
7
40
  const selectedSnapshotRef = hooks.useRef();
8
41
  const getSelectedSnapshot = () => {
@@ -13,7 +46,7 @@ function useSyncExternalStoreWithSelector(subscribe, getSnapshot, selector, isEq
13
46
  }
14
47
  return selectedSnapshotRef.current;
15
48
  };
16
- return compat.useSyncExternalStore(subscribe, getSelectedSnapshot);
49
+ return useSyncExternalStore(subscribe, getSelectedSnapshot);
17
50
  }
18
51
  function useStore(store2, selector = (d) => d, options = {}) {
19
52
  const equal = options.equal ?? shallow;
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../src/index.ts"],"sourcesContent":["import { useSyncExternalStore } from 'preact/compat'\nimport { useRef } from 'preact/hooks'\nimport type { Derived, Store } from '@tanstack/store'\n\nexport * from '@tanstack/store'\n\n/**\n * @private\n */\nexport type NoInfer<T> = [T][T extends any ? 0 : never]\ntype EqualityFn<T> = (objA: T, objB: T) => boolean\ninterface UseStoreOptions<T> {\n equal?: EqualityFn<T>\n}\n\nfunction useSyncExternalStoreWithSelector<TSnapshot, TSelected>(\n subscribe: (onStoreChange: () => void) => () => void,\n getSnapshot: () => TSnapshot,\n selector: (snapshot: TSnapshot) => TSelected,\n isEqual: (a: TSelected, b: TSelected) => boolean,\n): TSelected {\n const selectedSnapshotRef = useRef<TSelected | undefined>()\n\n const getSelectedSnapshot = () => {\n const snapshot = getSnapshot()\n const selected = selector(snapshot)\n\n if (\n selectedSnapshotRef.current === undefined ||\n !isEqual(selectedSnapshotRef.current, selected)\n ) {\n selectedSnapshotRef.current = selected\n }\n\n return selectedSnapshotRef.current\n }\n\n return useSyncExternalStore(subscribe, getSelectedSnapshot)\n}\n\nexport function useStore<TState, TSelected = NoInfer<TState>>(\n store: Store<TState, any>,\n selector?: (state: NoInfer<TState>) => TSelected,\n options?: UseStoreOptions<TSelected>,\n): TSelected\nexport function useStore<TState, TSelected = NoInfer<TState>>(\n store: Derived<TState, any>,\n selector?: (state: NoInfer<TState>) => TSelected,\n options?: UseStoreOptions<TSelected>,\n): TSelected\nexport function useStore<TState, TSelected = NoInfer<TState>>(\n store: Store<TState, any> | Derived<TState, any>,\n selector: (state: NoInfer<TState>) => TSelected = (d) => d as any,\n options: UseStoreOptions<TSelected> = {},\n): TSelected {\n const equal = options.equal ?? shallow\n const slice = useSyncExternalStoreWithSelector(\n store.subscribe,\n () => store.state,\n selector,\n equal,\n )\n\n return slice\n}\n\nexport function shallow<T>(objA: T, objB: T) {\n if (Object.is(objA, objB)) {\n return true\n }\n\n if (\n typeof objA !== 'object' ||\n objA === null ||\n typeof objB !== 'object' ||\n objB === null\n ) {\n return false\n }\n\n if (objA instanceof Map && objB instanceof Map) {\n if (objA.size !== objB.size) return false\n for (const [k, v] of objA) {\n if (!objB.has(k) || !Object.is(v, objB.get(k))) return false\n }\n return true\n }\n\n if (objA instanceof Set && objB instanceof Set) {\n if (objA.size !== objB.size) return false\n for (const v of objA) {\n if (!objB.has(v)) return false\n }\n return true\n }\n\n if (objA instanceof Date && objB instanceof Date) {\n if (objA.getTime() !== objB.getTime()) return false\n return true\n }\n\n const keysA = getOwnKeys(objA)\n if (keysA.length !== getOwnKeys(objB).length) {\n return false\n }\n\n for (const key of keysA) {\n if (\n !Object.prototype.hasOwnProperty.call(objB, key as string) ||\n !Object.is(objA[key as keyof T], objB[key as keyof T])\n ) {\n return false\n }\n }\n return true\n}\n\nfunction getOwnKeys(obj: object): Array<string | symbol> {\n return (Object.keys(obj) as Array<string | symbol>).concat(\n Object.getOwnPropertySymbols(obj),\n )\n}\n\n// force\n"],"names":["useRef","useSyncExternalStore","store"],"mappings":";;;;;AAeA,SAAS,iCACP,WACA,aACA,UACA,SACW;AACX,QAAM,sBAAsBA,MAAAA,OAAA;AAE5B,QAAM,sBAAsB,MAAM;AAChC,UAAM,WAAW,YAAA;AACjB,UAAM,WAAW,SAAS,QAAQ;AAElC,QACE,oBAAoB,YAAY,UAChC,CAAC,QAAQ,oBAAoB,SAAS,QAAQ,GAC9C;AACA,0BAAoB,UAAU;AAAA,IAChC;AAEA,WAAO,oBAAoB;AAAA,EAC7B;AAEA,SAAOC,OAAAA,qBAAqB,WAAW,mBAAmB;AAC5D;AAYO,SAAS,SACdC,QACA,WAAkD,CAAC,MAAM,GACzD,UAAsC,IAC3B;AACX,QAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAM,QAAQ;AAAA,IACZA,OAAM;AAAA,IACN,MAAMA,OAAM;AAAA,IACZ;AAAA,IACA;AAAA,EAAA;AAGF,SAAO;AACT;AAEO,SAAS,QAAW,MAAS,MAAS;AAC3C,MAAI,OAAO,GAAG,MAAM,IAAI,GAAG;AACzB,WAAO;AAAA,EACT;AAEA,MACE,OAAO,SAAS,YAChB,SAAS,QACT,OAAO,SAAS,YAChB,SAAS,MACT;AACA,WAAO;AAAA,EACT;AAEA,MAAI,gBAAgB,OAAO,gBAAgB,KAAK;AAC9C,QAAI,KAAK,SAAS,KAAK,KAAM,QAAO;AACpC,eAAW,CAAC,GAAG,CAAC,KAAK,MAAM;AACzB,UAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,GAAG,KAAK,IAAI,CAAC,CAAC,EAAG,QAAO;AAAA,IACzD;AACA,WAAO;AAAA,EACT;AAEA,MAAI,gBAAgB,OAAO,gBAAgB,KAAK;AAC9C,QAAI,KAAK,SAAS,KAAK,KAAM,QAAO;AACpC,eAAW,KAAK,MAAM;AACpB,UAAI,CAAC,KAAK,IAAI,CAAC,EAAG,QAAO;AAAA,IAC3B;AACA,WAAO;AAAA,EACT;AAEA,MAAI,gBAAgB,QAAQ,gBAAgB,MAAM;AAChD,QAAI,KAAK,QAAA,MAAc,KAAK,QAAA,EAAW,QAAO;AAC9C,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,WAAW,IAAI;AAC7B,MAAI,MAAM,WAAW,WAAW,IAAI,EAAE,QAAQ;AAC5C,WAAO;AAAA,EACT;AAEA,aAAW,OAAO,OAAO;AACvB,QACE,CAAC,OAAO,UAAU,eAAe,KAAK,MAAM,GAAa,KACzD,CAAC,OAAO,GAAG,KAAK,GAAc,GAAG,KAAK,GAAc,CAAC,GACrD;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,WAAW,KAAqC;AACvD,SAAQ,OAAO,KAAK,GAAG,EAA6B;AAAA,IAClD,OAAO,sBAAsB,GAAG;AAAA,EAAA;AAEpC;;;;;;;;;"}
1
+ {"version":3,"file":"index.cjs","sources":["../../src/index.ts"],"sourcesContent":["import { useEffect, useLayoutEffect, useRef, useState } from 'preact/hooks'\nimport type { Derived, Store } from '@tanstack/store'\n\nexport * from '@tanstack/store'\n\ntype InternalStore = {\n _value: any\n _getSnapshot: () => any\n}\n\ntype StoreRef = {\n _instance: InternalStore\n}\n\n/**\n * This is taken from https://github.com/preactjs/preact/blob/main/compat/src/hooks.js#L8-L54\n * which is taken from https://github.com/facebook/react/blob/main/packages/use-sync-external-store/src/useSyncExternalStoreShimClient.js#L84\n * on a high level this cuts out the warnings, ... and attempts a smaller implementation.\n * This way we don't have to import preact/compat with side effects\n */\nfunction useSyncExternalStore(\n subscribe: (onStoreChange: () => void) => () => void,\n getSnapshot: () => any,\n) {\n const value = getSnapshot()\n\n const [{ _instance }, forceUpdate] = useState<StoreRef>({\n _instance: { _value: value, _getSnapshot: getSnapshot },\n })\n\n useLayoutEffect(() => {\n _instance._value = value\n _instance._getSnapshot = getSnapshot\n\n if (didSnapshotChange(_instance)) {\n forceUpdate({ _instance })\n }\n }, [subscribe, value, getSnapshot])\n\n useEffect(() => {\n if (didSnapshotChange(_instance)) {\n forceUpdate({ _instance })\n }\n\n return subscribe(() => {\n if (didSnapshotChange(_instance)) {\n forceUpdate({ _instance })\n }\n })\n }, [subscribe])\n\n return value\n}\n\nfunction didSnapshotChange(inst: {\n _getSnapshot: () => any\n _value: any\n}): boolean {\n const latestGetSnapshot = inst._getSnapshot\n const prevValue = inst._value\n try {\n const nextValue = latestGetSnapshot()\n return !Object.is(prevValue, nextValue)\n // eslint-disable-next-line no-unused-vars\n } catch (_error) {\n return true\n }\n}\n\n/**\n * @private\n */\nexport type NoInfer<T> = [T][T extends any ? 0 : never]\ntype EqualityFn<T> = (objA: T, objB: T) => boolean\ninterface UseStoreOptions<T> {\n equal?: EqualityFn<T>\n}\n\nfunction useSyncExternalStoreWithSelector<TSnapshot, TSelected>(\n subscribe: (onStoreChange: () => void) => () => void,\n getSnapshot: () => TSnapshot,\n selector: (snapshot: TSnapshot) => TSelected,\n isEqual: (a: TSelected, b: TSelected) => boolean,\n): TSelected {\n const selectedSnapshotRef = useRef<TSelected | undefined>()\n\n const getSelectedSnapshot = () => {\n const snapshot = getSnapshot()\n const selected = selector(snapshot)\n\n if (\n selectedSnapshotRef.current === undefined ||\n !isEqual(selectedSnapshotRef.current, selected)\n ) {\n selectedSnapshotRef.current = selected\n }\n\n return selectedSnapshotRef.current\n }\n\n return useSyncExternalStore(subscribe, getSelectedSnapshot)\n}\n\nexport function useStore<TState, TSelected = NoInfer<TState>>(\n store: Store<TState, any>,\n selector?: (state: NoInfer<TState>) => TSelected,\n options?: UseStoreOptions<TSelected>,\n): TSelected\nexport function useStore<TState, TSelected = NoInfer<TState>>(\n store: Derived<TState, any>,\n selector?: (state: NoInfer<TState>) => TSelected,\n options?: UseStoreOptions<TSelected>,\n): TSelected\nexport function useStore<TState, TSelected = NoInfer<TState>>(\n store: Store<TState, any> | Derived<TState, any>,\n selector: (state: NoInfer<TState>) => TSelected = (d) => d as any,\n options: UseStoreOptions<TSelected> = {},\n): TSelected {\n const equal = options.equal ?? shallow\n const slice = useSyncExternalStoreWithSelector(\n store.subscribe,\n () => store.state,\n selector,\n equal,\n )\n\n return slice\n}\n\nexport function shallow<T>(objA: T, objB: T) {\n if (Object.is(objA, objB)) {\n return true\n }\n\n if (\n typeof objA !== 'object' ||\n objA === null ||\n typeof objB !== 'object' ||\n objB === null\n ) {\n return false\n }\n\n if (objA instanceof Map && objB instanceof Map) {\n if (objA.size !== objB.size) return false\n for (const [k, v] of objA) {\n if (!objB.has(k) || !Object.is(v, objB.get(k))) return false\n }\n return true\n }\n\n if (objA instanceof Set && objB instanceof Set) {\n if (objA.size !== objB.size) return false\n for (const v of objA) {\n if (!objB.has(v)) return false\n }\n return true\n }\n\n if (objA instanceof Date && objB instanceof Date) {\n if (objA.getTime() !== objB.getTime()) return false\n return true\n }\n\n const keysA = getOwnKeys(objA)\n if (keysA.length !== getOwnKeys(objB).length) {\n return false\n }\n\n for (const key of keysA) {\n if (\n !Object.prototype.hasOwnProperty.call(objB, key as string) ||\n !Object.is(objA[key as keyof T], objB[key as keyof T])\n ) {\n return false\n }\n }\n return true\n}\n\nfunction getOwnKeys(obj: object): Array<string | symbol> {\n return (Object.keys(obj) as Array<string | symbol>).concat(\n Object.getOwnPropertySymbols(obj),\n )\n}\n"],"names":["useState","useLayoutEffect","useEffect","useRef","store"],"mappings":"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"}
package/dist/esm/index.js CHANGED
@@ -1,6 +1,39 @@
1
- import { useSyncExternalStore } from "preact/compat";
2
- import { useRef } from "preact/hooks";
1
+ import { useRef, useState, useLayoutEffect, useEffect } from "preact/hooks";
3
2
  export * from "@tanstack/store";
3
+ function useSyncExternalStore(subscribe, getSnapshot) {
4
+ const value = getSnapshot();
5
+ const [{ _instance }, forceUpdate] = useState({
6
+ _instance: { _value: value, _getSnapshot: getSnapshot }
7
+ });
8
+ useLayoutEffect(() => {
9
+ _instance._value = value;
10
+ _instance._getSnapshot = getSnapshot;
11
+ if (didSnapshotChange(_instance)) {
12
+ forceUpdate({ _instance });
13
+ }
14
+ }, [subscribe, value, getSnapshot]);
15
+ useEffect(() => {
16
+ if (didSnapshotChange(_instance)) {
17
+ forceUpdate({ _instance });
18
+ }
19
+ return subscribe(() => {
20
+ if (didSnapshotChange(_instance)) {
21
+ forceUpdate({ _instance });
22
+ }
23
+ });
24
+ }, [subscribe]);
25
+ return value;
26
+ }
27
+ function didSnapshotChange(inst) {
28
+ const latestGetSnapshot = inst._getSnapshot;
29
+ const prevValue = inst._value;
30
+ try {
31
+ const nextValue = latestGetSnapshot();
32
+ return !Object.is(prevValue, nextValue);
33
+ } catch (_error) {
34
+ return true;
35
+ }
36
+ }
4
37
  function useSyncExternalStoreWithSelector(subscribe, getSnapshot, selector, isEqual) {
5
38
  const selectedSnapshotRef = useRef();
6
39
  const getSelectedSnapshot = () => {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/index.ts"],"sourcesContent":["import { useSyncExternalStore } from 'preact/compat'\nimport { useRef } from 'preact/hooks'\nimport type { Derived, Store } from '@tanstack/store'\n\nexport * from '@tanstack/store'\n\n/**\n * @private\n */\nexport type NoInfer<T> = [T][T extends any ? 0 : never]\ntype EqualityFn<T> = (objA: T, objB: T) => boolean\ninterface UseStoreOptions<T> {\n equal?: EqualityFn<T>\n}\n\nfunction useSyncExternalStoreWithSelector<TSnapshot, TSelected>(\n subscribe: (onStoreChange: () => void) => () => void,\n getSnapshot: () => TSnapshot,\n selector: (snapshot: TSnapshot) => TSelected,\n isEqual: (a: TSelected, b: TSelected) => boolean,\n): TSelected {\n const selectedSnapshotRef = useRef<TSelected | undefined>()\n\n const getSelectedSnapshot = () => {\n const snapshot = getSnapshot()\n const selected = selector(snapshot)\n\n if (\n selectedSnapshotRef.current === undefined ||\n !isEqual(selectedSnapshotRef.current, selected)\n ) {\n selectedSnapshotRef.current = selected\n }\n\n return selectedSnapshotRef.current\n }\n\n return useSyncExternalStore(subscribe, getSelectedSnapshot)\n}\n\nexport function useStore<TState, TSelected = NoInfer<TState>>(\n store: Store<TState, any>,\n selector?: (state: NoInfer<TState>) => TSelected,\n options?: UseStoreOptions<TSelected>,\n): TSelected\nexport function useStore<TState, TSelected = NoInfer<TState>>(\n store: Derived<TState, any>,\n selector?: (state: NoInfer<TState>) => TSelected,\n options?: UseStoreOptions<TSelected>,\n): TSelected\nexport function useStore<TState, TSelected = NoInfer<TState>>(\n store: Store<TState, any> | Derived<TState, any>,\n selector: (state: NoInfer<TState>) => TSelected = (d) => d as any,\n options: UseStoreOptions<TSelected> = {},\n): TSelected {\n const equal = options.equal ?? shallow\n const slice = useSyncExternalStoreWithSelector(\n store.subscribe,\n () => store.state,\n selector,\n equal,\n )\n\n return slice\n}\n\nexport function shallow<T>(objA: T, objB: T) {\n if (Object.is(objA, objB)) {\n return true\n }\n\n if (\n typeof objA !== 'object' ||\n objA === null ||\n typeof objB !== 'object' ||\n objB === null\n ) {\n return false\n }\n\n if (objA instanceof Map && objB instanceof Map) {\n if (objA.size !== objB.size) return false\n for (const [k, v] of objA) {\n if (!objB.has(k) || !Object.is(v, objB.get(k))) return false\n }\n return true\n }\n\n if (objA instanceof Set && objB instanceof Set) {\n if (objA.size !== objB.size) return false\n for (const v of objA) {\n if (!objB.has(v)) return false\n }\n return true\n }\n\n if (objA instanceof Date && objB instanceof Date) {\n if (objA.getTime() !== objB.getTime()) return false\n return true\n }\n\n const keysA = getOwnKeys(objA)\n if (keysA.length !== getOwnKeys(objB).length) {\n return false\n }\n\n for (const key of keysA) {\n if (\n !Object.prototype.hasOwnProperty.call(objB, key as string) ||\n !Object.is(objA[key as keyof T], objB[key as keyof T])\n ) {\n return false\n }\n }\n return true\n}\n\nfunction getOwnKeys(obj: object): Array<string | symbol> {\n return (Object.keys(obj) as Array<string | symbol>).concat(\n Object.getOwnPropertySymbols(obj),\n )\n}\n\n// force\n"],"names":[],"mappings":";;;AAeA,SAAS,iCACP,WACA,aACA,UACA,SACW;AACX,QAAM,sBAAsB,OAAA;AAE5B,QAAM,sBAAsB,MAAM;AAChC,UAAM,WAAW,YAAA;AACjB,UAAM,WAAW,SAAS,QAAQ;AAElC,QACE,oBAAoB,YAAY,UAChC,CAAC,QAAQ,oBAAoB,SAAS,QAAQ,GAC9C;AACA,0BAAoB,UAAU;AAAA,IAChC;AAEA,WAAO,oBAAoB;AAAA,EAC7B;AAEA,SAAO,qBAAqB,WAAW,mBAAmB;AAC5D;AAYO,SAAS,SACd,OACA,WAAkD,CAAC,MAAM,GACzD,UAAsC,IAC3B;AACX,QAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAM,QAAQ;AAAA,IACZ,MAAM;AAAA,IACN,MAAM,MAAM;AAAA,IACZ;AAAA,IACA;AAAA,EAAA;AAGF,SAAO;AACT;AAEO,SAAS,QAAW,MAAS,MAAS;AAC3C,MAAI,OAAO,GAAG,MAAM,IAAI,GAAG;AACzB,WAAO;AAAA,EACT;AAEA,MACE,OAAO,SAAS,YAChB,SAAS,QACT,OAAO,SAAS,YAChB,SAAS,MACT;AACA,WAAO;AAAA,EACT;AAEA,MAAI,gBAAgB,OAAO,gBAAgB,KAAK;AAC9C,QAAI,KAAK,SAAS,KAAK,KAAM,QAAO;AACpC,eAAW,CAAC,GAAG,CAAC,KAAK,MAAM;AACzB,UAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,GAAG,KAAK,IAAI,CAAC,CAAC,EAAG,QAAO;AAAA,IACzD;AACA,WAAO;AAAA,EACT;AAEA,MAAI,gBAAgB,OAAO,gBAAgB,KAAK;AAC9C,QAAI,KAAK,SAAS,KAAK,KAAM,QAAO;AACpC,eAAW,KAAK,MAAM;AACpB,UAAI,CAAC,KAAK,IAAI,CAAC,EAAG,QAAO;AAAA,IAC3B;AACA,WAAO;AAAA,EACT;AAEA,MAAI,gBAAgB,QAAQ,gBAAgB,MAAM;AAChD,QAAI,KAAK,QAAA,MAAc,KAAK,QAAA,EAAW,QAAO;AAC9C,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,WAAW,IAAI;AAC7B,MAAI,MAAM,WAAW,WAAW,IAAI,EAAE,QAAQ;AAC5C,WAAO;AAAA,EACT;AAEA,aAAW,OAAO,OAAO;AACvB,QACE,CAAC,OAAO,UAAU,eAAe,KAAK,MAAM,GAAa,KACzD,CAAC,OAAO,GAAG,KAAK,GAAc,GAAG,KAAK,GAAc,CAAC,GACrD;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,WAAW,KAAqC;AACvD,SAAQ,OAAO,KAAK,GAAG,EAA6B;AAAA,IAClD,OAAO,sBAAsB,GAAG;AAAA,EAAA;AAEpC;"}
1
+ {"version":3,"file":"index.js","sources":["../../src/index.ts"],"sourcesContent":["import { useEffect, useLayoutEffect, useRef, useState } from 'preact/hooks'\nimport type { Derived, Store } from '@tanstack/store'\n\nexport * from '@tanstack/store'\n\ntype InternalStore = {\n _value: any\n _getSnapshot: () => any\n}\n\ntype StoreRef = {\n _instance: InternalStore\n}\n\n/**\n * This is taken from https://github.com/preactjs/preact/blob/main/compat/src/hooks.js#L8-L54\n * which is taken from https://github.com/facebook/react/blob/main/packages/use-sync-external-store/src/useSyncExternalStoreShimClient.js#L84\n * on a high level this cuts out the warnings, ... and attempts a smaller implementation.\n * This way we don't have to import preact/compat with side effects\n */\nfunction useSyncExternalStore(\n subscribe: (onStoreChange: () => void) => () => void,\n getSnapshot: () => any,\n) {\n const value = getSnapshot()\n\n const [{ _instance }, forceUpdate] = useState<StoreRef>({\n _instance: { _value: value, _getSnapshot: getSnapshot },\n })\n\n useLayoutEffect(() => {\n _instance._value = value\n _instance._getSnapshot = getSnapshot\n\n if (didSnapshotChange(_instance)) {\n forceUpdate({ _instance })\n }\n }, [subscribe, value, getSnapshot])\n\n useEffect(() => {\n if (didSnapshotChange(_instance)) {\n forceUpdate({ _instance })\n }\n\n return subscribe(() => {\n if (didSnapshotChange(_instance)) {\n forceUpdate({ _instance })\n }\n })\n }, [subscribe])\n\n return value\n}\n\nfunction didSnapshotChange(inst: {\n _getSnapshot: () => any\n _value: any\n}): boolean {\n const latestGetSnapshot = inst._getSnapshot\n const prevValue = inst._value\n try {\n const nextValue = latestGetSnapshot()\n return !Object.is(prevValue, nextValue)\n // eslint-disable-next-line no-unused-vars\n } catch (_error) {\n return true\n }\n}\n\n/**\n * @private\n */\nexport type NoInfer<T> = [T][T extends any ? 0 : never]\ntype EqualityFn<T> = (objA: T, objB: T) => boolean\ninterface UseStoreOptions<T> {\n equal?: EqualityFn<T>\n}\n\nfunction useSyncExternalStoreWithSelector<TSnapshot, TSelected>(\n subscribe: (onStoreChange: () => void) => () => void,\n getSnapshot: () => TSnapshot,\n selector: (snapshot: TSnapshot) => TSelected,\n isEqual: (a: TSelected, b: TSelected) => boolean,\n): TSelected {\n const selectedSnapshotRef = useRef<TSelected | undefined>()\n\n const getSelectedSnapshot = () => {\n const snapshot = getSnapshot()\n const selected = selector(snapshot)\n\n if (\n selectedSnapshotRef.current === undefined ||\n !isEqual(selectedSnapshotRef.current, selected)\n ) {\n selectedSnapshotRef.current = selected\n }\n\n return selectedSnapshotRef.current\n }\n\n return useSyncExternalStore(subscribe, getSelectedSnapshot)\n}\n\nexport function useStore<TState, TSelected = NoInfer<TState>>(\n store: Store<TState, any>,\n selector?: (state: NoInfer<TState>) => TSelected,\n options?: UseStoreOptions<TSelected>,\n): TSelected\nexport function useStore<TState, TSelected = NoInfer<TState>>(\n store: Derived<TState, any>,\n selector?: (state: NoInfer<TState>) => TSelected,\n options?: UseStoreOptions<TSelected>,\n): TSelected\nexport function useStore<TState, TSelected = NoInfer<TState>>(\n store: Store<TState, any> | Derived<TState, any>,\n selector: (state: NoInfer<TState>) => TSelected = (d) => d as any,\n options: UseStoreOptions<TSelected> = {},\n): TSelected {\n const equal = options.equal ?? shallow\n const slice = useSyncExternalStoreWithSelector(\n store.subscribe,\n () => store.state,\n selector,\n equal,\n )\n\n return slice\n}\n\nexport function shallow<T>(objA: T, objB: T) {\n if (Object.is(objA, objB)) {\n return true\n }\n\n if (\n typeof objA !== 'object' ||\n objA === null ||\n typeof objB !== 'object' ||\n objB === null\n ) {\n return false\n }\n\n if (objA instanceof Map && objB instanceof Map) {\n if (objA.size !== objB.size) return false\n for (const [k, v] of objA) {\n if (!objB.has(k) || !Object.is(v, objB.get(k))) return false\n }\n return true\n }\n\n if (objA instanceof Set && objB instanceof Set) {\n if (objA.size !== objB.size) return false\n for (const v of objA) {\n if (!objB.has(v)) return false\n }\n return true\n }\n\n if (objA instanceof Date && objB instanceof Date) {\n if (objA.getTime() !== objB.getTime()) return false\n return true\n }\n\n const keysA = getOwnKeys(objA)\n if (keysA.length !== getOwnKeys(objB).length) {\n return false\n }\n\n for (const key of keysA) {\n if (\n !Object.prototype.hasOwnProperty.call(objB, key as string) ||\n !Object.is(objA[key as keyof T], objB[key as keyof T])\n ) {\n return false\n }\n }\n return true\n}\n\nfunction getOwnKeys(obj: object): Array<string | symbol> {\n return (Object.keys(obj) as Array<string | symbol>).concat(\n Object.getOwnPropertySymbols(obj),\n )\n}\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/preact-store",
3
- "version": "0.10.0",
3
+ "version": "0.10.2",
4
4
  "description": "Framework agnostic type-safe store w/ reactive framework adapters",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -42,7 +42,7 @@
42
42
  "src"
43
43
  ],
44
44
  "dependencies": {
45
- "@tanstack/store": "0.8.0"
45
+ "@tanstack/store": "0.8.1"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@preact/preset-vite": "^2.10.2",
package/src/index.ts CHANGED
@@ -1,9 +1,72 @@
1
- import { useSyncExternalStore } from 'preact/compat'
2
- import { useRef } from 'preact/hooks'
1
+ import { useEffect, useLayoutEffect, useRef, useState } from 'preact/hooks'
3
2
  import type { Derived, Store } from '@tanstack/store'
4
3
 
5
4
  export * from '@tanstack/store'
6
5
 
6
+ type InternalStore = {
7
+ _value: any
8
+ _getSnapshot: () => any
9
+ }
10
+
11
+ type StoreRef = {
12
+ _instance: InternalStore
13
+ }
14
+
15
+ /**
16
+ * This is taken from https://github.com/preactjs/preact/blob/main/compat/src/hooks.js#L8-L54
17
+ * which is taken from https://github.com/facebook/react/blob/main/packages/use-sync-external-store/src/useSyncExternalStoreShimClient.js#L84
18
+ * on a high level this cuts out the warnings, ... and attempts a smaller implementation.
19
+ * This way we don't have to import preact/compat with side effects
20
+ */
21
+ function useSyncExternalStore(
22
+ subscribe: (onStoreChange: () => void) => () => void,
23
+ getSnapshot: () => any,
24
+ ) {
25
+ const value = getSnapshot()
26
+
27
+ const [{ _instance }, forceUpdate] = useState<StoreRef>({
28
+ _instance: { _value: value, _getSnapshot: getSnapshot },
29
+ })
30
+
31
+ useLayoutEffect(() => {
32
+ _instance._value = value
33
+ _instance._getSnapshot = getSnapshot
34
+
35
+ if (didSnapshotChange(_instance)) {
36
+ forceUpdate({ _instance })
37
+ }
38
+ }, [subscribe, value, getSnapshot])
39
+
40
+ useEffect(() => {
41
+ if (didSnapshotChange(_instance)) {
42
+ forceUpdate({ _instance })
43
+ }
44
+
45
+ return subscribe(() => {
46
+ if (didSnapshotChange(_instance)) {
47
+ forceUpdate({ _instance })
48
+ }
49
+ })
50
+ }, [subscribe])
51
+
52
+ return value
53
+ }
54
+
55
+ function didSnapshotChange(inst: {
56
+ _getSnapshot: () => any
57
+ _value: any
58
+ }): boolean {
59
+ const latestGetSnapshot = inst._getSnapshot
60
+ const prevValue = inst._value
61
+ try {
62
+ const nextValue = latestGetSnapshot()
63
+ return !Object.is(prevValue, nextValue)
64
+ // eslint-disable-next-line no-unused-vars
65
+ } catch (_error) {
66
+ return true
67
+ }
68
+ }
69
+
7
70
  /**
8
71
  * @private
9
72
  */
@@ -120,5 +183,3 @@ function getOwnKeys(obj: object): Array<string | symbol> {
120
183
  Object.getOwnPropertySymbols(obj),
121
184
  )
122
185
  }
123
-
124
- // force