@kheopskit/react 0.0.25 → 1.0.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.d.mts CHANGED
@@ -2,10 +2,29 @@ import * as _kheopskit_core from '@kheopskit/core';
2
2
  import { KheopskitConfig } from '@kheopskit/core';
3
3
  import { FC, PropsWithChildren } from 'react';
4
4
 
5
- declare const useWallets: () => _kheopskit_core.KheopskitState;
6
-
7
- declare const KheopskitProvider: FC<PropsWithChildren & {
5
+ type KheopskitProviderProps = PropsWithChildren & {
8
6
  config?: Partial<KheopskitConfig>;
9
- }>;
7
+ /**
8
+ * Cookie string for SSR hydration.
9
+ * Pass the request cookie header (e.g., from Next.js headers or TanStack Start)
10
+ * to hydrate wallet state on the server.
11
+ *
12
+ * @remarks
13
+ * This value should be stable per render to avoid unnecessary store recreation.
14
+ * Compute it once in your server component or layout and pass it down.
15
+ *
16
+ * @example
17
+ * ```tsx
18
+ * // Next.js App Router
19
+ * const cookieStore = await cookies();
20
+ * const ssrCookies = cookieStore.getAll().map(c => `${c.name}=${c.value}`).join('; ');
21
+ * return <Providers ssrCookies={ssrCookies}>{children}</Providers>
22
+ * ```
23
+ */
24
+ ssrCookies?: string;
25
+ };
26
+ declare const KheopskitProvider: FC<KheopskitProviderProps>;
27
+
28
+ declare const useWallets: () => _kheopskit_core.KheopskitState;
10
29
 
11
- export { KheopskitProvider, useWallets };
30
+ export { KheopskitProvider, type KheopskitProviderProps, useWallets };
package/dist/index.d.ts CHANGED
@@ -2,10 +2,29 @@ import * as _kheopskit_core from '@kheopskit/core';
2
2
  import { KheopskitConfig } from '@kheopskit/core';
3
3
  import { FC, PropsWithChildren } from 'react';
4
4
 
5
- declare const useWallets: () => _kheopskit_core.KheopskitState;
6
-
7
- declare const KheopskitProvider: FC<PropsWithChildren & {
5
+ type KheopskitProviderProps = PropsWithChildren & {
8
6
  config?: Partial<KheopskitConfig>;
9
- }>;
7
+ /**
8
+ * Cookie string for SSR hydration.
9
+ * Pass the request cookie header (e.g., from Next.js headers or TanStack Start)
10
+ * to hydrate wallet state on the server.
11
+ *
12
+ * @remarks
13
+ * This value should be stable per render to avoid unnecessary store recreation.
14
+ * Compute it once in your server component or layout and pass it down.
15
+ *
16
+ * @example
17
+ * ```tsx
18
+ * // Next.js App Router
19
+ * const cookieStore = await cookies();
20
+ * const ssrCookies = cookieStore.getAll().map(c => `${c.name}=${c.value}`).join('; ');
21
+ * return <Providers ssrCookies={ssrCookies}>{children}</Providers>
22
+ * ```
23
+ */
24
+ ssrCookies?: string;
25
+ };
26
+ declare const KheopskitProvider: FC<KheopskitProviderProps>;
27
+
28
+ declare const useWallets: () => _kheopskit_core.KheopskitState;
10
29
 
11
- export { KheopskitProvider, useWallets };
30
+ export { KheopskitProvider, type KheopskitProviderProps, useWallets };
package/dist/index.js CHANGED
@@ -25,44 +25,52 @@ __export(index_exports, {
25
25
  });
26
26
  module.exports = __toCommonJS(index_exports);
27
27
 
28
- // src/useWallets.ts
28
+ // src/KheopskitProvider.tsx
29
+ var import_core = require("@kheopskit/core");
29
30
  var import_react2 = require("react");
30
31
 
31
32
  // src/context.ts
32
33
  var import_react = require("react");
33
34
  var KheopskitContext = (0, import_react.createContext)(null);
34
35
 
35
- // src/useWallets.ts
36
- var useWallets = () => {
37
- const ctx = (0, import_react2.useContext)(KheopskitContext);
38
- if (!ctx)
39
- throw new Error("useWallets can't be used without a KheopskitProvider");
40
- return ctx.state;
41
- };
42
-
43
- // src/KheopskitProvider.tsx
44
- var import_core = require("@kheopskit/core");
45
- var import_react3 = require("react");
46
-
47
36
  // src/createStore.ts
48
- var import_rxjs = require("rxjs");
49
- var createStore = (observable$, initialValue) => {
50
- const subject = new import_rxjs.BehaviorSubject(initialValue);
51
- const sub = observable$.subscribe((value) => {
52
- subject.next(value);
53
- });
54
- const getSnapshot = () => subject.getValue();
37
+ var createStore = (observable$, initialValue, serverValue) => {
38
+ let latestValue = null;
39
+ let subscription = null;
40
+ let subscriberCount = 0;
41
+ const listeners = /* @__PURE__ */ new Set();
42
+ const ensureSubscription = () => {
43
+ if (!subscription || subscription.closed) {
44
+ subscription = observable$.subscribe((value) => {
45
+ latestValue = value;
46
+ for (const listener of listeners) {
47
+ listener(value);
48
+ }
49
+ });
50
+ }
51
+ };
52
+ ensureSubscription();
53
+ const getSnapshot = () => latestValue ?? initialValue;
54
+ const getServerSnapshot = () => serverValue ?? initialValue;
55
55
  const subscribe = (callback) => {
56
- const sub2 = subject.subscribe(callback);
56
+ subscriberCount++;
57
+ listeners.add(callback);
58
+ ensureSubscription();
59
+ callback(getSnapshot());
57
60
  return () => {
58
- sub2.unsubscribe();
61
+ subscriberCount--;
62
+ listeners.delete(callback);
59
63
  };
60
64
  };
61
65
  const destroy = () => {
62
- sub.unsubscribe();
66
+ if (subscriberCount === 0 && subscription) {
67
+ subscription.unsubscribe();
68
+ subscription = null;
69
+ }
63
70
  };
64
71
  return {
65
72
  getSnapshot,
73
+ getServerSnapshot,
66
74
  subscribe,
67
75
  destroy
68
76
  };
@@ -70,23 +78,79 @@ var createStore = (observable$, initialValue) => {
70
78
 
71
79
  // src/KheopskitProvider.tsx
72
80
  var import_jsx_runtime = require("react/jsx-runtime");
73
- var KheopskitProvider = ({ children, config }) => {
74
- const defaultValue = (0, import_react3.useMemo)(
75
- () => ({
76
- wallets: [],
77
- accounts: [],
78
- config: (0, import_core.resolveConfig)(config)
81
+ var KheopskitProvider = ({
82
+ children,
83
+ config,
84
+ ssrCookies
85
+ }) => {
86
+ const resolvedConfig = (0, import_react2.useMemo)(() => (0, import_core.resolveConfig)(config), [config]);
87
+ const kheopskitStore = (0, import_react2.useMemo)(
88
+ () => (0, import_core.createKheopskitStore)({
89
+ ssrCookies,
90
+ storageKey: resolvedConfig.storageKey
79
91
  }),
80
- [config]
92
+ [ssrCookies, resolvedConfig.storageKey]
81
93
  );
82
- const store = (0, import_react3.useMemo)(
83
- () => createStore((0, import_core.getKheopskit$)(config), defaultValue),
84
- [config, defaultValue]
94
+ const serverValue = (0, import_react2.useMemo)(() => {
95
+ if (ssrCookies === void 0) {
96
+ return {
97
+ wallets: [],
98
+ accounts: [],
99
+ config: resolvedConfig,
100
+ isHydrating: true
101
+ };
102
+ }
103
+ const cached = kheopskitStore.getCachedState();
104
+ return {
105
+ wallets: cached.wallets.map(import_core.hydrateWallet),
106
+ accounts: cached.accounts.map(import_core.hydrateAccount),
107
+ config: resolvedConfig,
108
+ isHydrating: true
109
+ };
110
+ }, [ssrCookies, kheopskitStore, resolvedConfig]);
111
+ const initialValue = (0, import_react2.useMemo)(() => {
112
+ const enrichedWallets = serverValue.wallets.map((w) => {
113
+ if (!w.icon) {
114
+ const cachedIcon = (0, import_core.getCachedIcon)(w.id);
115
+ if (cachedIcon) {
116
+ return { ...w, icon: cachedIcon };
117
+ }
118
+ }
119
+ return w;
120
+ });
121
+ return {
122
+ ...serverValue,
123
+ wallets: enrichedWallets
124
+ };
125
+ }, [serverValue]);
126
+ const store = (0, import_react2.useMemo)(
127
+ () => createStore(
128
+ (0, import_core.getKheopskit$)(config, ssrCookies, kheopskitStore),
129
+ initialValue,
130
+ serverValue
131
+ ),
132
+ [config, ssrCookies, kheopskitStore, initialValue, serverValue]
85
133
  );
86
- const state = (0, import_react3.useSyncExternalStore)(store.subscribe, store.getSnapshot);
87
- const value = (0, import_react3.useMemo)(() => ({ state }), [state]);
134
+ (0, import_react2.useEffect)(() => {
135
+ return () => store.destroy();
136
+ }, [store]);
137
+ const state = (0, import_react2.useSyncExternalStore)(
138
+ store.subscribe,
139
+ store.getSnapshot,
140
+ store.getServerSnapshot
141
+ );
142
+ const value = (0, import_react2.useMemo)(() => ({ state }), [state]);
88
143
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(KheopskitContext.Provider, { value, children });
89
144
  };
145
+
146
+ // src/useWallets.ts
147
+ var import_react3 = require("react");
148
+ var useWallets = () => {
149
+ const ctx = (0, import_react3.useContext)(KheopskitContext);
150
+ if (!ctx)
151
+ throw new Error("useWallets can't be used without a KheopskitProvider");
152
+ return ctx.state;
153
+ };
90
154
  // Annotate the CommonJS export names for ESM import in node:
91
155
  0 && (module.exports = {
92
156
  KheopskitProvider,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/useWallets.ts","../src/context.ts","../src/KheopskitProvider.tsx","../src/createStore.ts"],"sourcesContent":["export * from \"./useWallets\";\nexport * from \"./KheopskitProvider\";\n","import { useContext } from \"react\";\nimport { KheopskitContext } from \"./context\";\n\nexport const useWallets = () => {\n const ctx = useContext(KheopskitContext);\n\n // useEffect(() => {\n // console.debug(\n // \"useWallets wallets:%s accounts:%s\",\n // ctx?.state.wallets.length ?? 0,\n // ctx?.state.accounts.length ?? 0,\n // );\n // }, [ctx?.state]);\n\n if (!ctx)\n throw new Error(\"useWallets can't be used without a KheopskitProvider\");\n\n return ctx.state;\n};\n","import type { KheopskitState } from \"@kheopskit/core\";\nimport { createContext } from \"react\";\n\nexport const KheopskitContext = createContext<{\n state: KheopskitState;\n} | null>(null);\n","import {\n type KheopskitConfig,\n type KheopskitState,\n getKheopskit$,\n resolveConfig,\n} from \"@kheopskit/core\";\nimport {\n type FC,\n type PropsWithChildren,\n useMemo,\n useSyncExternalStore,\n} from \"react\";\nimport { KheopskitContext } from \"./context\";\nimport { createStore } from \"./createStore\";\n\nexport const KheopskitProvider: FC<\n PropsWithChildren & { config?: Partial<KheopskitConfig> }\n> = ({ children, config }) => {\n const defaultValue = useMemo<KheopskitState>(\n () => ({\n wallets: [],\n accounts: [],\n config: resolveConfig(config),\n }),\n [config],\n );\n\n const store = useMemo(\n () => createStore(getKheopskit$(config), defaultValue),\n [config, defaultValue],\n );\n\n const state = useSyncExternalStore(store.subscribe, store.getSnapshot);\n\n const value = useMemo(() => ({ state }), [state]);\n\n return (\n <KheopskitContext.Provider value={value}>\n {children}\n </KheopskitContext.Provider>\n );\n};\n","import { BehaviorSubject, type Observable } from \"rxjs\";\n\nexport const createStore = <T>(observable$: Observable<T>, initialValue: T) => {\n const subject = new BehaviorSubject<T>(initialValue);\n\n const sub = observable$.subscribe((value) => {\n subject.next(value);\n });\n\n const getSnapshot = () => subject.getValue();\n\n const subscribe = (callback: (value: T) => void) => {\n const sub = subject.subscribe(callback);\n\n return () => {\n sub.unsubscribe();\n };\n };\n\n const destroy = () => {\n sub.unsubscribe();\n };\n\n return {\n getSnapshot,\n subscribe,\n destroy,\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,gBAA2B;;;ACC3B,mBAA8B;AAEvB,IAAM,uBAAmB,4BAEtB,IAAI;;;ADFP,IAAM,aAAa,MAAM;AAC9B,QAAM,UAAM,0BAAW,gBAAgB;AAUvC,MAAI,CAAC;AACH,UAAM,IAAI,MAAM,sDAAsD;AAExE,SAAO,IAAI;AACb;;;AElBA,kBAKO;AACP,IAAAC,gBAKO;;;ACXP,kBAAiD;AAE1C,IAAM,cAAc,CAAI,aAA4B,iBAAoB;AAC7E,QAAM,UAAU,IAAI,4BAAmB,YAAY;AAEnD,QAAM,MAAM,YAAY,UAAU,CAAC,UAAU;AAC3C,YAAQ,KAAK,KAAK;AAAA,EACpB,CAAC;AAED,QAAM,cAAc,MAAM,QAAQ,SAAS;AAE3C,QAAM,YAAY,CAAC,aAAiC;AAClD,UAAMC,OAAM,QAAQ,UAAU,QAAQ;AAEtC,WAAO,MAAM;AACX,MAAAA,KAAI,YAAY;AAAA,IAClB;AAAA,EACF;AAEA,QAAM,UAAU,MAAM;AACpB,QAAI,YAAY;AAAA,EAClB;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;ADSI;AAtBG,IAAM,oBAET,CAAC,EAAE,UAAU,OAAO,MAAM;AAC5B,QAAM,mBAAe;AAAA,IACnB,OAAO;AAAA,MACL,SAAS,CAAC;AAAA,MACV,UAAU,CAAC;AAAA,MACX,YAAQ,2BAAc,MAAM;AAAA,IAC9B;AAAA,IACA,CAAC,MAAM;AAAA,EACT;AAEA,QAAM,YAAQ;AAAA,IACZ,MAAM,gBAAY,2BAAc,MAAM,GAAG,YAAY;AAAA,IACrD,CAAC,QAAQ,YAAY;AAAA,EACvB;AAEA,QAAM,YAAQ,oCAAqB,MAAM,WAAW,MAAM,WAAW;AAErE,QAAM,YAAQ,uBAAQ,OAAO,EAAE,MAAM,IAAI,CAAC,KAAK,CAAC;AAEhD,SACE,4CAAC,iBAAiB,UAAjB,EAA0B,OACxB,UACH;AAEJ;","names":["import_react","import_react","sub"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/KheopskitProvider.tsx","../src/context.ts","../src/createStore.ts","../src/useWallets.ts"],"sourcesContent":["export * from \"./KheopskitProvider\";\nexport * from \"./useWallets\";\n","import {\n\tcreateKheopskitStore,\n\tgetCachedIcon,\n\tgetKheopskit$,\n\thydrateAccount,\n\thydrateWallet,\n\ttype KheopskitConfig,\n\ttype KheopskitState,\n\tresolveConfig,\n} from \"@kheopskit/core\";\nimport {\n\ttype FC,\n\ttype PropsWithChildren,\n\tuseEffect,\n\tuseMemo,\n\tuseSyncExternalStore,\n} from \"react\";\nimport { KheopskitContext } from \"./context\";\nimport { createStore } from \"./createStore\";\n\nexport type KheopskitProviderProps = PropsWithChildren & {\n\tconfig?: Partial<KheopskitConfig>;\n\t/**\n\t * Cookie string for SSR hydration.\n\t * Pass the request cookie header (e.g., from Next.js headers or TanStack Start)\n\t * to hydrate wallet state on the server.\n\t *\n\t * @remarks\n\t * This value should be stable per render to avoid unnecessary store recreation.\n\t * Compute it once in your server component or layout and pass it down.\n\t *\n\t * @example\n\t * ```tsx\n\t * // Next.js App Router\n\t * const cookieStore = await cookies();\n\t * const ssrCookies = cookieStore.getAll().map(c => `${c.name}=${c.value}`).join('; ');\n\t * return <Providers ssrCookies={ssrCookies}>{children}</Providers>\n\t * ```\n\t */\n\tssrCookies?: string;\n};\n\nexport const KheopskitProvider: FC<KheopskitProviderProps> = ({\n\tchildren,\n\tconfig,\n\tssrCookies,\n}) => {\n\tconst resolvedConfig = useMemo(() => resolveConfig(config), [config]);\n\n\t// Create a single store for both reading cached state and powering the observable\n\tconst kheopskitStore = useMemo(\n\t\t() =>\n\t\t\tcreateKheopskitStore({\n\t\t\t\tssrCookies,\n\t\t\t\tstorageKey: resolvedConfig.storageKey,\n\t\t\t}),\n\t\t[ssrCookies, resolvedConfig.storageKey],\n\t);\n\n\t// Read cached state from the store for SSR hydration\n\t// This produces wallets WITHOUT localStorage icons (Ethereum wallets have no icon)\n\t// because localStorage isn't available on server\n\tconst serverValue = useMemo<KheopskitState>(() => {\n\t\tif (ssrCookies === undefined) {\n\t\t\treturn {\n\t\t\t\twallets: [],\n\t\t\t\taccounts: [],\n\t\t\t\tconfig: resolvedConfig,\n\t\t\t\tisHydrating: true,\n\t\t\t};\n\t\t}\n\t\tconst cached = kheopskitStore.getCachedState();\n\t\treturn {\n\t\t\twallets: cached.wallets.map(hydrateWallet),\n\t\t\taccounts: cached.accounts.map(hydrateAccount),\n\t\t\tconfig: resolvedConfig,\n\t\t\tisHydrating: true,\n\t\t};\n\t}, [ssrCookies, kheopskitStore, resolvedConfig]);\n\n\t// Initial value for client includes localStorage icons\n\t// This is what we WANT the client to render, not what server rendered\n\tconst initialValue = useMemo<KheopskitState>(() => {\n\t\t// On client, enrich wallets with localStorage icons\n\t\t// getCachedIcon returns empty on server (no localStorage), so this is safe\n\t\tconst enrichedWallets = serverValue.wallets.map((w) => {\n\t\t\tif (!w.icon) {\n\t\t\t\tconst cachedIcon = getCachedIcon(w.id);\n\t\t\t\tif (cachedIcon) {\n\t\t\t\t\treturn { ...w, icon: cachedIcon };\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn w;\n\t\t});\n\t\treturn {\n\t\t\t...serverValue,\n\t\t\twallets: enrichedWallets,\n\t\t};\n\t}, [serverValue]);\n\n\tconst store = useMemo(\n\t\t() =>\n\t\t\tcreateStore(\n\t\t\t\tgetKheopskit$(config, ssrCookies, kheopskitStore),\n\t\t\t\tinitialValue,\n\t\t\t\tserverValue,\n\t\t\t),\n\t\t[config, ssrCookies, kheopskitStore, initialValue, serverValue],\n\t);\n\n\t// Cleanup store subscriptions when store changes or component unmounts\n\tuseEffect(() => {\n\t\treturn () => store.destroy();\n\t}, [store]);\n\n\tconst state = useSyncExternalStore(\n\t\tstore.subscribe,\n\t\tstore.getSnapshot,\n\t\tstore.getServerSnapshot,\n\t);\n\n\tconst value = useMemo(() => ({ state }), [state]);\n\n\treturn (\n\t\t<KheopskitContext.Provider value={value}>\n\t\t\t{children}\n\t\t</KheopskitContext.Provider>\n\t);\n};\n","import type { KheopskitState } from \"@kheopskit/core\";\nimport { createContext } from \"react\";\n\nexport const KheopskitContext = createContext<{\n\tstate: KheopskitState;\n} | null>(null);\n","import type { Observable, Subscription } from \"rxjs\";\n\nexport const createStore = <T>(\n\tobservable$: Observable<T>,\n\tinitialValue: T,\n\tserverValue?: T,\n) => {\n\t// Use null as sentinel to indicate we haven't received first emission yet\n\tlet latestValue: T | null = null;\n\tlet subscription: Subscription | null = null;\n\tlet subscriberCount = 0;\n\tconst listeners = new Set<(value: T) => void>();\n\n\tconst ensureSubscription = () => {\n\t\tif (!subscription || subscription.closed) {\n\t\t\tsubscription = observable$.subscribe((value) => {\n\t\t\t\tlatestValue = value;\n\t\t\t\tfor (const listener of listeners) {\n\t\t\t\t\tlistener(value);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t};\n\n\t// Start subscription immediately\n\tensureSubscription();\n\n\t// If observable emitted synchronously, use that value\n\t// Otherwise fall back to initialValue\n\tconst getSnapshot = () => latestValue ?? initialValue;\n\n\t/**\n\t * Returns the server-side snapshot for SSR hydration.\n\t * This prevents hydration mismatches by providing a consistent\n\t * value during server rendering. Must return the same value as\n\t * what the server rendered.\n\t */\n\tconst getServerSnapshot = () => serverValue ?? initialValue;\n\n\tconst subscribe = (callback: (value: T) => void) => {\n\t\tsubscriberCount++;\n\t\tlisteners.add(callback);\n\t\t// Ensure observable subscription is active when someone subscribes\n\t\tensureSubscription();\n\n\t\t// Immediately emit current value (BehaviorSubject semantics)\n\t\tcallback(getSnapshot());\n\n\t\treturn () => {\n\t\t\tsubscriberCount--;\n\t\t\tlisteners.delete(callback);\n\t\t\t// Don't close the observable subscription on unsubscribe\n\t\t\t// Let destroy() handle that when the store is truly being disposed\n\t\t};\n\t};\n\n\tconst destroy = () => {\n\t\t// Only unsubscribe if no one is listening\n\t\t// React StrictMode may call destroy and then immediately resubscribe\n\t\tif (subscriberCount === 0 && subscription) {\n\t\t\tsubscription.unsubscribe();\n\t\t\tsubscription = null;\n\t\t}\n\t};\n\n\treturn {\n\t\tgetSnapshot,\n\t\tgetServerSnapshot,\n\t\tsubscribe,\n\t\tdestroy,\n\t};\n};\n","import { useContext } from \"react\";\nimport { KheopskitContext } from \"./context\";\n\nexport const useWallets = () => {\n\tconst ctx = useContext(KheopskitContext);\n\n\t// useEffect(() => {\n\t// console.debug(\n\t// \"useWallets wallets:%s accounts:%s\",\n\t// ctx?.state.wallets.length ?? 0,\n\t// ctx?.state.accounts.length ?? 0,\n\t// );\n\t// }, [ctx?.state]);\n\n\tif (!ctx)\n\t\tthrow new Error(\"useWallets can't be used without a KheopskitProvider\");\n\n\treturn ctx.state;\n};\n"],"mappings":"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","names":["import_react","import_react"]}
package/dist/index.mjs CHANGED
@@ -1,47 +1,60 @@
1
- // src/useWallets.ts
2
- import { useContext } from "react";
3
-
4
- // src/context.ts
5
- import { createContext } from "react";
6
- var KheopskitContext = createContext(null);
7
-
8
- // src/useWallets.ts
9
- var useWallets = () => {
10
- const ctx = useContext(KheopskitContext);
11
- if (!ctx)
12
- throw new Error("useWallets can't be used without a KheopskitProvider");
13
- return ctx.state;
14
- };
15
-
16
1
  // src/KheopskitProvider.tsx
17
2
  import {
3
+ createKheopskitStore,
4
+ getCachedIcon,
18
5
  getKheopskit$,
6
+ hydrateAccount,
7
+ hydrateWallet,
19
8
  resolveConfig
20
9
  } from "@kheopskit/core";
21
10
  import {
11
+ useEffect,
22
12
  useMemo,
23
13
  useSyncExternalStore
24
14
  } from "react";
25
15
 
16
+ // src/context.ts
17
+ import { createContext } from "react";
18
+ var KheopskitContext = createContext(null);
19
+
26
20
  // src/createStore.ts
27
- import { BehaviorSubject } from "rxjs";
28
- var createStore = (observable$, initialValue) => {
29
- const subject = new BehaviorSubject(initialValue);
30
- const sub = observable$.subscribe((value) => {
31
- subject.next(value);
32
- });
33
- const getSnapshot = () => subject.getValue();
21
+ var createStore = (observable$, initialValue, serverValue) => {
22
+ let latestValue = null;
23
+ let subscription = null;
24
+ let subscriberCount = 0;
25
+ const listeners = /* @__PURE__ */ new Set();
26
+ const ensureSubscription = () => {
27
+ if (!subscription || subscription.closed) {
28
+ subscription = observable$.subscribe((value) => {
29
+ latestValue = value;
30
+ for (const listener of listeners) {
31
+ listener(value);
32
+ }
33
+ });
34
+ }
35
+ };
36
+ ensureSubscription();
37
+ const getSnapshot = () => latestValue ?? initialValue;
38
+ const getServerSnapshot = () => serverValue ?? initialValue;
34
39
  const subscribe = (callback) => {
35
- const sub2 = subject.subscribe(callback);
40
+ subscriberCount++;
41
+ listeners.add(callback);
42
+ ensureSubscription();
43
+ callback(getSnapshot());
36
44
  return () => {
37
- sub2.unsubscribe();
45
+ subscriberCount--;
46
+ listeners.delete(callback);
38
47
  };
39
48
  };
40
49
  const destroy = () => {
41
- sub.unsubscribe();
50
+ if (subscriberCount === 0 && subscription) {
51
+ subscription.unsubscribe();
52
+ subscription = null;
53
+ }
42
54
  };
43
55
  return {
44
56
  getSnapshot,
57
+ getServerSnapshot,
45
58
  subscribe,
46
59
  destroy
47
60
  };
@@ -49,23 +62,79 @@ var createStore = (observable$, initialValue) => {
49
62
 
50
63
  // src/KheopskitProvider.tsx
51
64
  import { jsx } from "react/jsx-runtime";
52
- var KheopskitProvider = ({ children, config }) => {
53
- const defaultValue = useMemo(
54
- () => ({
55
- wallets: [],
56
- accounts: [],
57
- config: resolveConfig(config)
65
+ var KheopskitProvider = ({
66
+ children,
67
+ config,
68
+ ssrCookies
69
+ }) => {
70
+ const resolvedConfig = useMemo(() => resolveConfig(config), [config]);
71
+ const kheopskitStore = useMemo(
72
+ () => createKheopskitStore({
73
+ ssrCookies,
74
+ storageKey: resolvedConfig.storageKey
58
75
  }),
59
- [config]
76
+ [ssrCookies, resolvedConfig.storageKey]
60
77
  );
78
+ const serverValue = useMemo(() => {
79
+ if (ssrCookies === void 0) {
80
+ return {
81
+ wallets: [],
82
+ accounts: [],
83
+ config: resolvedConfig,
84
+ isHydrating: true
85
+ };
86
+ }
87
+ const cached = kheopskitStore.getCachedState();
88
+ return {
89
+ wallets: cached.wallets.map(hydrateWallet),
90
+ accounts: cached.accounts.map(hydrateAccount),
91
+ config: resolvedConfig,
92
+ isHydrating: true
93
+ };
94
+ }, [ssrCookies, kheopskitStore, resolvedConfig]);
95
+ const initialValue = useMemo(() => {
96
+ const enrichedWallets = serverValue.wallets.map((w) => {
97
+ if (!w.icon) {
98
+ const cachedIcon = getCachedIcon(w.id);
99
+ if (cachedIcon) {
100
+ return { ...w, icon: cachedIcon };
101
+ }
102
+ }
103
+ return w;
104
+ });
105
+ return {
106
+ ...serverValue,
107
+ wallets: enrichedWallets
108
+ };
109
+ }, [serverValue]);
61
110
  const store = useMemo(
62
- () => createStore(getKheopskit$(config), defaultValue),
63
- [config, defaultValue]
111
+ () => createStore(
112
+ getKheopskit$(config, ssrCookies, kheopskitStore),
113
+ initialValue,
114
+ serverValue
115
+ ),
116
+ [config, ssrCookies, kheopskitStore, initialValue, serverValue]
117
+ );
118
+ useEffect(() => {
119
+ return () => store.destroy();
120
+ }, [store]);
121
+ const state = useSyncExternalStore(
122
+ store.subscribe,
123
+ store.getSnapshot,
124
+ store.getServerSnapshot
64
125
  );
65
- const state = useSyncExternalStore(store.subscribe, store.getSnapshot);
66
126
  const value = useMemo(() => ({ state }), [state]);
67
127
  return /* @__PURE__ */ jsx(KheopskitContext.Provider, { value, children });
68
128
  };
129
+
130
+ // src/useWallets.ts
131
+ import { useContext } from "react";
132
+ var useWallets = () => {
133
+ const ctx = useContext(KheopskitContext);
134
+ if (!ctx)
135
+ throw new Error("useWallets can't be used without a KheopskitProvider");
136
+ return ctx.state;
137
+ };
69
138
  export {
70
139
  KheopskitProvider,
71
140
  useWallets
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/useWallets.ts","../src/context.ts","../src/KheopskitProvider.tsx","../src/createStore.ts"],"sourcesContent":["import { useContext } from \"react\";\nimport { KheopskitContext } from \"./context\";\n\nexport const useWallets = () => {\n const ctx = useContext(KheopskitContext);\n\n // useEffect(() => {\n // console.debug(\n // \"useWallets wallets:%s accounts:%s\",\n // ctx?.state.wallets.length ?? 0,\n // ctx?.state.accounts.length ?? 0,\n // );\n // }, [ctx?.state]);\n\n if (!ctx)\n throw new Error(\"useWallets can't be used without a KheopskitProvider\");\n\n return ctx.state;\n};\n","import type { KheopskitState } from \"@kheopskit/core\";\nimport { createContext } from \"react\";\n\nexport const KheopskitContext = createContext<{\n state: KheopskitState;\n} | null>(null);\n","import {\n type KheopskitConfig,\n type KheopskitState,\n getKheopskit$,\n resolveConfig,\n} from \"@kheopskit/core\";\nimport {\n type FC,\n type PropsWithChildren,\n useMemo,\n useSyncExternalStore,\n} from \"react\";\nimport { KheopskitContext } from \"./context\";\nimport { createStore } from \"./createStore\";\n\nexport const KheopskitProvider: FC<\n PropsWithChildren & { config?: Partial<KheopskitConfig> }\n> = ({ children, config }) => {\n const defaultValue = useMemo<KheopskitState>(\n () => ({\n wallets: [],\n accounts: [],\n config: resolveConfig(config),\n }),\n [config],\n );\n\n const store = useMemo(\n () => createStore(getKheopskit$(config), defaultValue),\n [config, defaultValue],\n );\n\n const state = useSyncExternalStore(store.subscribe, store.getSnapshot);\n\n const value = useMemo(() => ({ state }), [state]);\n\n return (\n <KheopskitContext.Provider value={value}>\n {children}\n </KheopskitContext.Provider>\n );\n};\n","import { BehaviorSubject, type Observable } from \"rxjs\";\n\nexport const createStore = <T>(observable$: Observable<T>, initialValue: T) => {\n const subject = new BehaviorSubject<T>(initialValue);\n\n const sub = observable$.subscribe((value) => {\n subject.next(value);\n });\n\n const getSnapshot = () => subject.getValue();\n\n const subscribe = (callback: (value: T) => void) => {\n const sub = subject.subscribe(callback);\n\n return () => {\n sub.unsubscribe();\n };\n };\n\n const destroy = () => {\n sub.unsubscribe();\n };\n\n return {\n getSnapshot,\n subscribe,\n destroy,\n };\n};\n"],"mappings":";AAAA,SAAS,kBAAkB;;;ACC3B,SAAS,qBAAqB;AAEvB,IAAM,mBAAmB,cAEtB,IAAI;;;ADFP,IAAM,aAAa,MAAM;AAC9B,QAAM,MAAM,WAAW,gBAAgB;AAUvC,MAAI,CAAC;AACH,UAAM,IAAI,MAAM,sDAAsD;AAExE,SAAO,IAAI;AACb;;;AElBA;AAAA,EAGE;AAAA,EACA;AAAA,OACK;AACP;AAAA,EAGE;AAAA,EACA;AAAA,OACK;;;ACXP,SAAS,uBAAwC;AAE1C,IAAM,cAAc,CAAI,aAA4B,iBAAoB;AAC7E,QAAM,UAAU,IAAI,gBAAmB,YAAY;AAEnD,QAAM,MAAM,YAAY,UAAU,CAAC,UAAU;AAC3C,YAAQ,KAAK,KAAK;AAAA,EACpB,CAAC;AAED,QAAM,cAAc,MAAM,QAAQ,SAAS;AAE3C,QAAM,YAAY,CAAC,aAAiC;AAClD,UAAMA,OAAM,QAAQ,UAAU,QAAQ;AAEtC,WAAO,MAAM;AACX,MAAAA,KAAI,YAAY;AAAA,IAClB;AAAA,EACF;AAEA,QAAM,UAAU,MAAM;AACpB,QAAI,YAAY;AAAA,EAClB;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;ADSI;AAtBG,IAAM,oBAET,CAAC,EAAE,UAAU,OAAO,MAAM;AAC5B,QAAM,eAAe;AAAA,IACnB,OAAO;AAAA,MACL,SAAS,CAAC;AAAA,MACV,UAAU,CAAC;AAAA,MACX,QAAQ,cAAc,MAAM;AAAA,IAC9B;AAAA,IACA,CAAC,MAAM;AAAA,EACT;AAEA,QAAM,QAAQ;AAAA,IACZ,MAAM,YAAY,cAAc,MAAM,GAAG,YAAY;AAAA,IACrD,CAAC,QAAQ,YAAY;AAAA,EACvB;AAEA,QAAM,QAAQ,qBAAqB,MAAM,WAAW,MAAM,WAAW;AAErE,QAAM,QAAQ,QAAQ,OAAO,EAAE,MAAM,IAAI,CAAC,KAAK,CAAC;AAEhD,SACE,oBAAC,iBAAiB,UAAjB,EAA0B,OACxB,UACH;AAEJ;","names":["sub"]}
1
+ {"version":3,"sources":["../src/KheopskitProvider.tsx","../src/context.ts","../src/createStore.ts","../src/useWallets.ts"],"sourcesContent":["import {\n\tcreateKheopskitStore,\n\tgetCachedIcon,\n\tgetKheopskit$,\n\thydrateAccount,\n\thydrateWallet,\n\ttype KheopskitConfig,\n\ttype KheopskitState,\n\tresolveConfig,\n} from \"@kheopskit/core\";\nimport {\n\ttype FC,\n\ttype PropsWithChildren,\n\tuseEffect,\n\tuseMemo,\n\tuseSyncExternalStore,\n} from \"react\";\nimport { KheopskitContext } from \"./context\";\nimport { createStore } from \"./createStore\";\n\nexport type KheopskitProviderProps = PropsWithChildren & {\n\tconfig?: Partial<KheopskitConfig>;\n\t/**\n\t * Cookie string for SSR hydration.\n\t * Pass the request cookie header (e.g., from Next.js headers or TanStack Start)\n\t * to hydrate wallet state on the server.\n\t *\n\t * @remarks\n\t * This value should be stable per render to avoid unnecessary store recreation.\n\t * Compute it once in your server component or layout and pass it down.\n\t *\n\t * @example\n\t * ```tsx\n\t * // Next.js App Router\n\t * const cookieStore = await cookies();\n\t * const ssrCookies = cookieStore.getAll().map(c => `${c.name}=${c.value}`).join('; ');\n\t * return <Providers ssrCookies={ssrCookies}>{children}</Providers>\n\t * ```\n\t */\n\tssrCookies?: string;\n};\n\nexport const KheopskitProvider: FC<KheopskitProviderProps> = ({\n\tchildren,\n\tconfig,\n\tssrCookies,\n}) => {\n\tconst resolvedConfig = useMemo(() => resolveConfig(config), [config]);\n\n\t// Create a single store for both reading cached state and powering the observable\n\tconst kheopskitStore = useMemo(\n\t\t() =>\n\t\t\tcreateKheopskitStore({\n\t\t\t\tssrCookies,\n\t\t\t\tstorageKey: resolvedConfig.storageKey,\n\t\t\t}),\n\t\t[ssrCookies, resolvedConfig.storageKey],\n\t);\n\n\t// Read cached state from the store for SSR hydration\n\t// This produces wallets WITHOUT localStorage icons (Ethereum wallets have no icon)\n\t// because localStorage isn't available on server\n\tconst serverValue = useMemo<KheopskitState>(() => {\n\t\tif (ssrCookies === undefined) {\n\t\t\treturn {\n\t\t\t\twallets: [],\n\t\t\t\taccounts: [],\n\t\t\t\tconfig: resolvedConfig,\n\t\t\t\tisHydrating: true,\n\t\t\t};\n\t\t}\n\t\tconst cached = kheopskitStore.getCachedState();\n\t\treturn {\n\t\t\twallets: cached.wallets.map(hydrateWallet),\n\t\t\taccounts: cached.accounts.map(hydrateAccount),\n\t\t\tconfig: resolvedConfig,\n\t\t\tisHydrating: true,\n\t\t};\n\t}, [ssrCookies, kheopskitStore, resolvedConfig]);\n\n\t// Initial value for client includes localStorage icons\n\t// This is what we WANT the client to render, not what server rendered\n\tconst initialValue = useMemo<KheopskitState>(() => {\n\t\t// On client, enrich wallets with localStorage icons\n\t\t// getCachedIcon returns empty on server (no localStorage), so this is safe\n\t\tconst enrichedWallets = serverValue.wallets.map((w) => {\n\t\t\tif (!w.icon) {\n\t\t\t\tconst cachedIcon = getCachedIcon(w.id);\n\t\t\t\tif (cachedIcon) {\n\t\t\t\t\treturn { ...w, icon: cachedIcon };\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn w;\n\t\t});\n\t\treturn {\n\t\t\t...serverValue,\n\t\t\twallets: enrichedWallets,\n\t\t};\n\t}, [serverValue]);\n\n\tconst store = useMemo(\n\t\t() =>\n\t\t\tcreateStore(\n\t\t\t\tgetKheopskit$(config, ssrCookies, kheopskitStore),\n\t\t\t\tinitialValue,\n\t\t\t\tserverValue,\n\t\t\t),\n\t\t[config, ssrCookies, kheopskitStore, initialValue, serverValue],\n\t);\n\n\t// Cleanup store subscriptions when store changes or component unmounts\n\tuseEffect(() => {\n\t\treturn () => store.destroy();\n\t}, [store]);\n\n\tconst state = useSyncExternalStore(\n\t\tstore.subscribe,\n\t\tstore.getSnapshot,\n\t\tstore.getServerSnapshot,\n\t);\n\n\tconst value = useMemo(() => ({ state }), [state]);\n\n\treturn (\n\t\t<KheopskitContext.Provider value={value}>\n\t\t\t{children}\n\t\t</KheopskitContext.Provider>\n\t);\n};\n","import type { KheopskitState } from \"@kheopskit/core\";\nimport { createContext } from \"react\";\n\nexport const KheopskitContext = createContext<{\n\tstate: KheopskitState;\n} | null>(null);\n","import type { Observable, Subscription } from \"rxjs\";\n\nexport const createStore = <T>(\n\tobservable$: Observable<T>,\n\tinitialValue: T,\n\tserverValue?: T,\n) => {\n\t// Use null as sentinel to indicate we haven't received first emission yet\n\tlet latestValue: T | null = null;\n\tlet subscription: Subscription | null = null;\n\tlet subscriberCount = 0;\n\tconst listeners = new Set<(value: T) => void>();\n\n\tconst ensureSubscription = () => {\n\t\tif (!subscription || subscription.closed) {\n\t\t\tsubscription = observable$.subscribe((value) => {\n\t\t\t\tlatestValue = value;\n\t\t\t\tfor (const listener of listeners) {\n\t\t\t\t\tlistener(value);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t};\n\n\t// Start subscription immediately\n\tensureSubscription();\n\n\t// If observable emitted synchronously, use that value\n\t// Otherwise fall back to initialValue\n\tconst getSnapshot = () => latestValue ?? initialValue;\n\n\t/**\n\t * Returns the server-side snapshot for SSR hydration.\n\t * This prevents hydration mismatches by providing a consistent\n\t * value during server rendering. Must return the same value as\n\t * what the server rendered.\n\t */\n\tconst getServerSnapshot = () => serverValue ?? initialValue;\n\n\tconst subscribe = (callback: (value: T) => void) => {\n\t\tsubscriberCount++;\n\t\tlisteners.add(callback);\n\t\t// Ensure observable subscription is active when someone subscribes\n\t\tensureSubscription();\n\n\t\t// Immediately emit current value (BehaviorSubject semantics)\n\t\tcallback(getSnapshot());\n\n\t\treturn () => {\n\t\t\tsubscriberCount--;\n\t\t\tlisteners.delete(callback);\n\t\t\t// Don't close the observable subscription on unsubscribe\n\t\t\t// Let destroy() handle that when the store is truly being disposed\n\t\t};\n\t};\n\n\tconst destroy = () => {\n\t\t// Only unsubscribe if no one is listening\n\t\t// React StrictMode may call destroy and then immediately resubscribe\n\t\tif (subscriberCount === 0 && subscription) {\n\t\t\tsubscription.unsubscribe();\n\t\t\tsubscription = null;\n\t\t}\n\t};\n\n\treturn {\n\t\tgetSnapshot,\n\t\tgetServerSnapshot,\n\t\tsubscribe,\n\t\tdestroy,\n\t};\n};\n","import { useContext } from \"react\";\nimport { KheopskitContext } from \"./context\";\n\nexport const useWallets = () => {\n\tconst ctx = useContext(KheopskitContext);\n\n\t// useEffect(() => {\n\t// console.debug(\n\t// \"useWallets wallets:%s accounts:%s\",\n\t// ctx?.state.wallets.length ?? 0,\n\t// ctx?.state.accounts.length ?? 0,\n\t// );\n\t// }, [ctx?.state]);\n\n\tif (!ctx)\n\t\tthrow new Error(\"useWallets can't be used without a KheopskitProvider\");\n\n\treturn ctx.state;\n};\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@kheopskit/react",
3
- "version": "0.0.25",
3
+ "version": "1.0.0",
4
4
  "description": "",
5
- "publishConfig": {
6
- "access": "public"
7
- },
8
5
  "private": false,
9
- "main": "dist/index.cjs",
10
- "module": "dist/index.mjs",
11
- "types": "dist/index.d.ts",
6
+ "files": [
7
+ "dist"
8
+ ],
9
+ "main": "./dist/index.cjs",
10
+ "module": "./dist/index.mjs",
11
+ "types": "./dist/index.d.ts",
12
12
  "exports": {
13
13
  ".": {
14
14
  "types": "./dist/index.d.ts",
@@ -16,6 +16,9 @@
16
16
  "require": "./dist/index.cjs"
17
17
  }
18
18
  },
19
+ "publishConfig": {
20
+ "access": "public"
21
+ },
19
22
  "keywords": [],
20
23
  "author": "Kheops (https://github.com/0xKheops)",
21
24
  "repository": {
@@ -24,23 +27,24 @@
24
27
  },
25
28
  "license": "ISC",
26
29
  "peerDependencies": {
30
+ "@kheopskit/core": "^0.1.0",
27
31
  "react": ">=18.0.0",
28
32
  "react-dom": ">=18.0.0",
29
- "rxjs": ">=7.0.0",
30
- "@kheopskit/core": "0.0.21"
33
+ "rxjs": ">=7.0.0"
31
34
  },
32
35
  "devDependencies": {
33
- "@types/react": "^19.1.5",
34
- "@types/react-dom": "^19.1.5",
35
- "react": "^19.1.0",
36
- "react-dom": "^19.1.0",
36
+ "@types/react": "^19.2.11",
37
+ "@types/react-dom": "^19.2.3",
38
+ "react": "^19.2.4",
39
+ "react-dom": "^19.2.4",
37
40
  "rxjs": "^7.8.2",
38
- "@kheopskit/core": "0.0.21"
41
+ "@kheopskit/core": "0.1.0"
39
42
  },
40
43
  "tsup": {
41
44
  "entry": [
42
45
  "src/index.ts"
43
46
  ],
47
+ "tsconfig": "tsconfig.build.json",
44
48
  "splitting": false,
45
49
  "sourcemap": true,
46
50
  "clean": true,
@@ -55,6 +59,7 @@
55
59
  "test": "echo \"Error: no test specified\" && exit 1",
56
60
  "dev": "tsup --watch",
57
61
  "build": "tsup",
58
- "clean": "rm -rf ./dist && rm -rf ./node_modules"
62
+ "clean": "rm -rf ./dist && rm -rf ./node_modules",
63
+ "typecheck": "tsc --noEmit"
59
64
  }
60
65
  }
package/CHANGELOG.md DELETED
@@ -1,218 +0,0 @@
1
- # @kheopskit/react
2
-
3
- ## 0.0.25
4
-
5
- ### Patch Changes
6
-
7
- - Updated dependencies [[`b3d5f98`](https://github.com/kheopskit/kheopskit/commit/b3d5f989a33f9c13f56833f71494df5091c4930c), [`cd73eb1`](https://github.com/kheopskit/kheopskit/commit/cd73eb18840a69b49238629051450eca26b9e275)]:
8
- - @kheopskit/core@0.0.21
9
-
10
- ## 0.0.24
11
-
12
- ### Patch Changes
13
-
14
- - [`920ed5b`](https://github.com/kheopskit/kheopskit/commit/920ed5babefc6d38ddc18bde3d68ff945cd1a0af) Thanks [@0xKheops](https://github.com/0xKheops)! - fix: peer dep to core
15
-
16
- ## 0.0.23
17
-
18
- ### Patch Changes
19
-
20
- - [`87bbfb0`](https://github.com/kheopskit/kheopskit/commit/87bbfb016b15bd0378a62943ccbe1403a6e5d07e) Thanks [@0xKheops](https://github.com/0xKheops)! - test: changeset2
21
-
22
- - Updated dependencies [[`87bbfb0`](https://github.com/kheopskit/kheopskit/commit/87bbfb016b15bd0378a62943ccbe1403a6e5d07e)]:
23
- - @kheopskit/core@0.0.20
24
-
25
- ## 0.0.22
26
-
27
- ### Patch Changes
28
-
29
- - [`e68aaa5`](https://github.com/kheopskit/kheopskit/commit/e68aaa5019630b03660d1cb5e95a9188cf972ebf) Thanks [@0xKheops](https://github.com/0xKheops)! - test: changeset
30
-
31
- - Updated dependencies [[`e68aaa5`](https://github.com/kheopskit/kheopskit/commit/e68aaa5019630b03660d1cb5e95a9188cf972ebf)]:
32
- - @kheopskit/core@0.0.19
33
-
34
- ## 0.0.21
35
-
36
- ### Patch Changes
37
-
38
- - [`a35e7f9`](https://github.com/kheopskit/kheopskit/commit/a35e7f9808bd215088dbfb7747d217622e429618) Thanks [@0xKheops](https://github.com/0xKheops)! - test: changeset
39
-
40
- ## 0.0.20
41
-
42
- ### Patch Changes
43
-
44
- - [`0ada998`](https://github.com/kheopskit/kheopskit/commit/0ada998099206c0ba11451b25e0212cd511d6bcf) Thanks [@0xKheops](https://github.com/0xKheops)! - test: changeset
45
-
46
- ## 0.0.19
47
-
48
- ### Patch Changes
49
-
50
- - [`c660e23`](https://github.com/kheopskit/kheopskit/commit/c660e231aaed809d885b9ec29fd81b550a30c159) Thanks [@0xKheops](https://github.com/0xKheops)! - test: changeset
51
-
52
- ## 0.0.18
53
-
54
- ### Patch Changes
55
-
56
- - [`2e04a98`](https://github.com/kheopskit/kheopskit/commit/2e04a9893795e6aa43c942dee61443b4700c3294) Thanks [@0xKheops](https://github.com/0xKheops)! - fix: sync changesets
57
-
58
- - Updated dependencies [[`2e04a98`](https://github.com/kheopskit/kheopskit/commit/2e04a9893795e6aa43c942dee61443b4700c3294)]:
59
- - @kheopskit/core@0.0.18
60
-
61
- ## 0.0.17
62
-
63
- ### Patch Changes
64
-
65
- - [`91fe482`](https://github.com/kheopskit/kheopskit/commit/91fe4821c159f7b970b1a8aa52544b9eb63776bc) Thanks [@0xKheops](https://github.com/0xKheops)! - test: changeset
66
-
67
- ## 0.0.16
68
-
69
- ### Patch Changes
70
-
71
- - [`b69943f`](https://github.com/kheopskit/kheopskit/commit/b69943fafbbe34b8035e8030b615684c3c8d1a7e) Thanks [@0xKheops](https://github.com/0xKheops)! - test: changeset
72
-
73
- ## 0.0.15
74
-
75
- ### Patch Changes
76
-
77
- - [`a540c06`](https://github.com/kheopskit/kheopskit/commit/a540c06e90816656a1a21df3d95d0328bff78455) Thanks [@0xKheops](https://github.com/0xKheops)! - test: one more changeset
78
-
79
- - Updated dependencies [[`a540c06`](https://github.com/kheopskit/kheopskit/commit/a540c06e90816656a1a21df3d95d0328bff78455)]:
80
- - @kheopskit/core@0.0.15
81
-
82
- ## 0.0.14
83
-
84
- ### Patch Changes
85
-
86
- - Updated dependencies [[`b8242ab`](https://github.com/kheopskit/kheopskit/commit/b8242abd31a6512b16399dd44ca5e5d82f6c70bf)]:
87
- - @kheopskit/core@0.0.14
88
-
89
- ## 0.0.13
90
-
91
- ### Patch Changes
92
-
93
- - Updated dependencies [[`5e07091`](https://github.com/kheopskit/kheopskit/commit/5e070910229cb9202f5d2f1869bfb16c5180d273)]:
94
- - @kheopskit/core@0.0.13
95
-
96
- ## 0.0.12
97
-
98
- ### Patch Changes
99
-
100
- - Updated dependencies [[`2f34f0c`](https://github.com/kheopskit/kheopskit/commit/2f34f0c16c7866a4187b4474a45f93e2ad07f5c7)]:
101
- - @kheopskit/core@0.0.12
102
-
103
- ## 0.0.11
104
-
105
- ### Patch Changes
106
-
107
- - Updated dependencies [[`9d4f86e`](https://github.com/kheopskit/kheopskit/commit/9d4f86e7632843fad089ce930b209aee9b9e2b41)]:
108
- - @kheopskit/core@0.0.11
109
-
110
- ## 0.0.10
111
-
112
- ### Patch Changes
113
-
114
- - [`c7dea32`](https://github.com/kheopskit/kheopskit/commit/c7dea32e2921716cef82b53e1960c3cdb4c8e5ae) Thanks [@0xKheops](https://github.com/0xKheops)! - test changeset
115
-
116
- - Updated dependencies [[`c7dea32`](https://github.com/kheopskit/kheopskit/commit/c7dea32e2921716cef82b53e1960c3cdb4c8e5ae)]:
117
- - @kheopskit/core@0.0.10
118
-
119
- ## 0.0.9
120
-
121
- ### Patch Changes
122
-
123
- - [`961f6a3`](https://github.com/kheopskit/kheopskit/commit/961f6a371c73d4065e9157c95ca4d996012098e7) Thanks [@0xKheops](https://github.com/0xKheops)! - test changeset
124
-
125
- - Updated dependencies [[`961f6a3`](https://github.com/kheopskit/kheopskit/commit/961f6a371c73d4065e9157c95ca4d996012098e7)]:
126
- - @kheopskit/core@0.0.9
127
-
128
- ## 0.0.8
129
-
130
- ### Patch Changes
131
-
132
- - [`b76185f`](https://github.com/kheopskit/kheopskit/commit/b76185f99a78c5a82a8b9aead65b0708f17b0bd5) Thanks [@0xKheops](https://github.com/0xKheops)! - test changeset
133
-
134
- - Updated dependencies [[`b76185f`](https://github.com/kheopskit/kheopskit/commit/b76185f99a78c5a82a8b9aead65b0708f17b0bd5)]:
135
- - @kheopskit/core@0.0.8
136
-
137
- ## 0.0.7
138
-
139
- ### Patch Changes
140
-
141
- - [`07f8406`](https://github.com/kheopskit/kheopskit/commit/07f8406d3f176e6a8b3b06fe16396bf2b6b1db88) Thanks [@0xKheops](https://github.com/0xKheops)! - test changeset
142
-
143
- - Updated dependencies [[`07f8406`](https://github.com/kheopskit/kheopskit/commit/07f8406d3f176e6a8b3b06fe16396bf2b6b1db88)]:
144
- - @kheopskit/core@0.0.7
145
-
146
- ## 0.0.6
147
-
148
- ### Patch Changes
149
-
150
- - [`5319326`](https://github.com/kheopskit/kheopskit/commit/53193262e80fec9e242986f818d7f7b53f92357a) Thanks [@0xKheops](https://github.com/0xKheops)! - test changeset
151
-
152
- - Updated dependencies [[`5319326`](https://github.com/kheopskit/kheopskit/commit/53193262e80fec9e242986f818d7f7b53f92357a)]:
153
- - @kheopskit/core@0.0.6
154
-
155
- ## 0.0.5
156
-
157
- ### Patch Changes
158
-
159
- - [`d865842`](https://github.com/kheopskit/kheopskit/commit/d86584236e51730e82baaa9068604fa7e703e9c2) Thanks [@0xKheops](https://github.com/0xKheops)! - test changeset
160
-
161
- - Updated dependencies [[`d865842`](https://github.com/kheopskit/kheopskit/commit/d86584236e51730e82baaa9068604fa7e703e9c2)]:
162
- - @kheopskit/core@0.0.5
163
-
164
- ## 0.0.4
165
-
166
- ### Patch Changes
167
-
168
- - [`4a61939`](https://github.com/kheopskit/kheopskit/commit/4a61939b9a5c4ea6fb119a0427704a5fc684343e) Thanks [@0xKheops](https://github.com/0xKheops)! - test changeset
169
-
170
- - Updated dependencies [[`4a61939`](https://github.com/kheopskit/kheopskit/commit/4a61939b9a5c4ea6fb119a0427704a5fc684343e)]:
171
- - @kheopskit/core@0.0.4
172
-
173
- ## 0.0.3
174
-
175
- ### Patch Changes
176
-
177
- - [`7a0ea89`](https://github.com/kheopskit/kheopskit/commit/7a0ea890982570ae89934fead69d319fff46dd98) Thanks [@0xKheops](https://github.com/0xKheops)! - test changeset
178
-
179
- - Updated dependencies [[`7a0ea89`](https://github.com/kheopskit/kheopskit/commit/7a0ea890982570ae89934fead69d319fff46dd98)]:
180
- - @kheopskit/core@0.0.3
181
-
182
- ## 0.0.2
183
-
184
- ### Patch Changes
185
-
186
- - [`806b8d3`](https://github.com/kheopskit/kheopskit/commit/806b8d394ba7c2576c76d9de72a15d7927bcff9e) - update peer deps
187
-
188
- - Updated dependencies [[`806b8d3`](https://github.com/kheopskit/kheopskit/commit/806b8d394ba7c2576c76d9de72a15d7927bcff9e)]:
189
- - @kheopskit/core@0.0.2
190
-
191
- ## 0.0.1
192
-
193
- ### Patch Changes
194
-
195
- - [`e1cebed`](https://github.com/kheopskit/kheopskit/commit/e1cebed92d303f041070e0ae146ee34d9eb717bd) - refactor property names
196
-
197
- - [`e1cebed`](https://github.com/kheopskit/kheopskit/commit/e1cebed92d303f041070e0ae146ee34d9eb717bd) - initial alpha release
198
-
199
- - Updated dependencies [[`e1cebed`](https://github.com/kheopskit/kheopskit/commit/e1cebed92d303f041070e0ae146ee34d9eb717bd), [`e1cebed`](https://github.com/kheopskit/kheopskit/commit/e1cebed92d303f041070e0ae146ee34d9eb717bd)]:
200
- - @kheopskit/core@0.0.1
201
-
202
- ## 0.0.1-alpha.1
203
-
204
- ### Patch Changes
205
-
206
- - [`4f378f9`](https://github.com/0xKheops/kheopskit-alpha/commit/4f378f9b61e555b7b66ef3bfaf107ab8e6ac62b1) - refactor property names
207
-
208
- - Updated dependencies [[`4f378f9`](https://github.com/0xKheops/kheopskit-alpha/commit/4f378f9b61e555b7b66ef3bfaf107ab8e6ac62b1)]:
209
- - @kheopskit/core@0.0.1-alpha.1
210
-
211
- ## 0.0.1-alpha.0
212
-
213
- ### Patch Changes
214
-
215
- - [`3216d3b`](https://github.com/0xKheops/kheopskit-alpha/commit/3216d3b4ca1f2fadbebe9a4275e7b864ac89d222) - initial alpha release
216
-
217
- - Updated dependencies [[`3216d3b`](https://github.com/0xKheops/kheopskit-alpha/commit/3216d3b4ca1f2fadbebe9a4275e7b864ac89d222)]:
218
- - @kheopskit/core@0.0.1-alpha.0
@@ -1,42 +0,0 @@
1
- import {
2
- type KheopskitConfig,
3
- type KheopskitState,
4
- getKheopskit$,
5
- resolveConfig,
6
- } from "@kheopskit/core";
7
- import {
8
- type FC,
9
- type PropsWithChildren,
10
- useMemo,
11
- useSyncExternalStore,
12
- } from "react";
13
- import { KheopskitContext } from "./context";
14
- import { createStore } from "./createStore";
15
-
16
- export const KheopskitProvider: FC<
17
- PropsWithChildren & { config?: Partial<KheopskitConfig> }
18
- > = ({ children, config }) => {
19
- const defaultValue = useMemo<KheopskitState>(
20
- () => ({
21
- wallets: [],
22
- accounts: [],
23
- config: resolveConfig(config),
24
- }),
25
- [config],
26
- );
27
-
28
- const store = useMemo(
29
- () => createStore(getKheopskit$(config), defaultValue),
30
- [config, defaultValue],
31
- );
32
-
33
- const state = useSyncExternalStore(store.subscribe, store.getSnapshot);
34
-
35
- const value = useMemo(() => ({ state }), [state]);
36
-
37
- return (
38
- <KheopskitContext.Provider value={value}>
39
- {children}
40
- </KheopskitContext.Provider>
41
- );
42
- };
package/src/context.ts DELETED
@@ -1,6 +0,0 @@
1
- import type { KheopskitState } from "@kheopskit/core";
2
- import { createContext } from "react";
3
-
4
- export const KheopskitContext = createContext<{
5
- state: KheopskitState;
6
- } | null>(null);
@@ -1,29 +0,0 @@
1
- import { BehaviorSubject, type Observable } from "rxjs";
2
-
3
- export const createStore = <T>(observable$: Observable<T>, initialValue: T) => {
4
- const subject = new BehaviorSubject<T>(initialValue);
5
-
6
- const sub = observable$.subscribe((value) => {
7
- subject.next(value);
8
- });
9
-
10
- const getSnapshot = () => subject.getValue();
11
-
12
- const subscribe = (callback: (value: T) => void) => {
13
- const sub = subject.subscribe(callback);
14
-
15
- return () => {
16
- sub.unsubscribe();
17
- };
18
- };
19
-
20
- const destroy = () => {
21
- sub.unsubscribe();
22
- };
23
-
24
- return {
25
- getSnapshot,
26
- subscribe,
27
- destroy,
28
- };
29
- };
package/src/index.ts DELETED
@@ -1,2 +0,0 @@
1
- export * from "./useWallets";
2
- export * from "./KheopskitProvider";
package/src/useWallets.ts DELETED
@@ -1,19 +0,0 @@
1
- import { useContext } from "react";
2
- import { KheopskitContext } from "./context";
3
-
4
- export const useWallets = () => {
5
- const ctx = useContext(KheopskitContext);
6
-
7
- // useEffect(() => {
8
- // console.debug(
9
- // "useWallets wallets:%s accounts:%s",
10
- // ctx?.state.wallets.length ?? 0,
11
- // ctx?.state.accounts.length ?? 0,
12
- // );
13
- // }, [ctx?.state]);
14
-
15
- if (!ctx)
16
- throw new Error("useWallets can't be used without a KheopskitProvider");
17
-
18
- return ctx.state;
19
- };
package/tsconfig.json DELETED
@@ -1,11 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.base",
3
- "include": ["src", "tests"],
4
- "compilerOptions": {
5
- "jsx": "react-jsx",
6
- "baseUrl": "src",
7
- "paths": {
8
- "@/*": ["*"]
9
- }
10
- }
11
- }