@electric-sql/react 0.2.1 → 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/cjs/index.cjs +4 -20
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/index.browser.mjs +1 -1
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.d.ts +1 -11
- package/dist/index.legacy-esm.js +4 -18
- package/dist/index.legacy-esm.js.map +1 -1
- package/dist/index.mjs +4 -18
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/react-hooks.tsx +1 -32
package/dist/cjs/index.cjs
CHANGED
|
@@ -63,13 +63,11 @@ var __async = (__this, __arguments, generator) => {
|
|
|
63
63
|
// src/index.ts
|
|
64
64
|
var src_exports = {};
|
|
65
65
|
__export(src_exports, {
|
|
66
|
-
ShapesProvider: () => ShapesProvider,
|
|
67
66
|
getShape: () => getShape,
|
|
68
67
|
getShapeStream: () => getShapeStream,
|
|
69
68
|
preloadShape: () => preloadShape,
|
|
70
69
|
sortedOptionsHash: () => sortedOptionsHash,
|
|
71
|
-
useShape: () => useShape
|
|
72
|
-
useShapeContext: () => useShapeContext
|
|
70
|
+
useShape: () => useShape
|
|
73
71
|
});
|
|
74
72
|
module.exports = __toCommonJS(src_exports);
|
|
75
73
|
|
|
@@ -77,7 +75,6 @@ module.exports = __toCommonJS(src_exports);
|
|
|
77
75
|
var import_client = require("@electric-sql/client");
|
|
78
76
|
var import_react = __toESM(require("react"), 1);
|
|
79
77
|
var import_with_selector = require("use-sync-external-store/with-selector.js");
|
|
80
|
-
var ShapesContext = (0, import_react.createContext)(null);
|
|
81
78
|
var streamCache = /* @__PURE__ */ new Map();
|
|
82
79
|
var shapeCache = /* @__PURE__ */ new Map();
|
|
83
80
|
function preloadShape(options) {
|
|
@@ -110,16 +107,6 @@ function getShape(shapeStream) {
|
|
|
110
107
|
return newShape;
|
|
111
108
|
}
|
|
112
109
|
}
|
|
113
|
-
function ShapesProvider({ children }) {
|
|
114
|
-
return /* @__PURE__ */ import_react.default.createElement(ShapesContext.Provider, { value: { getShape, getShapeStream } }, children);
|
|
115
|
-
}
|
|
116
|
-
function useShapeContext() {
|
|
117
|
-
const context = (0, import_react.useContext)(ShapesContext);
|
|
118
|
-
if (!context) {
|
|
119
|
-
throw new Error(`useShapeContext must be used within a ShapeProvider`);
|
|
120
|
-
}
|
|
121
|
-
return context;
|
|
122
|
-
}
|
|
123
110
|
function shapeSubscribe(shape, callback) {
|
|
124
111
|
const unsubscribe = shape.subscribe(callback);
|
|
125
112
|
return () => {
|
|
@@ -142,9 +129,8 @@ function useShape(_a) {
|
|
|
142
129
|
} = _b, options = __objRest(_b, [
|
|
143
130
|
"selector"
|
|
144
131
|
]);
|
|
145
|
-
const
|
|
146
|
-
const
|
|
147
|
-
const shape = getShape2(shapeStream);
|
|
132
|
+
const shapeStream = getShapeStream(options);
|
|
133
|
+
const shape = getShape(shapeStream);
|
|
148
134
|
const latestShapeData = (0, import_react.useRef)(parseShapeData(shape));
|
|
149
135
|
const getSnapshot = import_react.default.useCallback(() => latestShapeData.current, []);
|
|
150
136
|
const shapeData = (0, import_with_selector.useSyncExternalStoreWithSelector)(
|
|
@@ -163,12 +149,10 @@ function useShape(_a) {
|
|
|
163
149
|
}
|
|
164
150
|
// Annotate the CommonJS export names for ESM import in node:
|
|
165
151
|
0 && (module.exports = {
|
|
166
|
-
ShapesProvider,
|
|
167
152
|
getShape,
|
|
168
153
|
getShapeStream,
|
|
169
154
|
preloadShape,
|
|
170
155
|
sortedOptionsHash,
|
|
171
|
-
useShape
|
|
172
|
-
useShapeContext
|
|
156
|
+
useShape
|
|
173
157
|
});
|
|
174
158
|
//# sourceMappingURL=index.cjs.map
|
package/dist/cjs/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts","../../src/react-hooks.tsx"],"sourcesContent":["export * from './react-hooks'\n","import {\n Value,\n Shape,\n ShapeStream,\n ShapeStreamOptions,\n} from '@electric-sql/client'\nimport React, {
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts","../../src/react-hooks.tsx"],"sourcesContent":["export * from './react-hooks'\n","import {\n Value,\n Shape,\n ShapeStream,\n ShapeStreamOptions,\n} from '@electric-sql/client'\nimport React, { useCallback, useRef } from 'react'\nimport { useSyncExternalStoreWithSelector } from 'use-sync-external-store/with-selector.js'\n\nconst streamCache = new Map<string, ShapeStream>()\nconst shapeCache = new Map<ShapeStream, Shape>()\n\nexport async function preloadShape(\n options: ShapeStreamOptions\n): Promise<Shape> {\n const shapeStream = getShapeStream(options)\n const shape = getShape(shapeStream)\n await shape.value\n return shape\n}\n\nexport function sortedOptionsHash(options: ShapeStreamOptions): string {\n return JSON.stringify(options, Object.keys(options).sort())\n}\n\nexport function getShapeStream(options: ShapeStreamOptions): ShapeStream {\n const shapeHash = sortedOptionsHash(options)\n\n // If the stream is already cached, return\n if (streamCache.has(shapeHash)) {\n // Return the ShapeStream\n return streamCache.get(shapeHash)!\n } else {\n const newShapeStream = new ShapeStream(options)\n\n streamCache.set(shapeHash, newShapeStream)\n\n // Return the created shape\n return newShapeStream\n }\n}\n\nexport function getShape(shapeStream: ShapeStream): Shape {\n // If the stream is already cached, return\n if (shapeCache.has(shapeStream)) {\n // Return the ShapeStream\n return shapeCache.get(shapeStream)!\n } else {\n const newShape = new Shape(shapeStream)\n\n shapeCache.set(shapeStream, newShape)\n\n // Return the created shape\n return newShape\n }\n}\n\ninterface UseShapeResult {\n /**\n * The array of rows that make up the Shape.\n * @type {{ [key: string]: Value }[]}\n */\n data: { [key: string]: Value }[]\n /**\n * The Shape instance used by this useShape\n * @type(Shape)\n */\n shape: Shape\n error: Shape[`error`]\n isError: boolean\n /**\n * Has the ShapeStream caught up with the replication log from Postgres.\n */\n isUpToDate: boolean\n}\n\nfunction shapeSubscribe(shape: Shape, callback: () => void) {\n const unsubscribe = shape.subscribe(callback)\n return () => {\n unsubscribe()\n }\n}\n\nfunction parseShapeData(shape: Shape): UseShapeResult {\n return {\n data: [...shape.valueSync.values()],\n isUpToDate: shape.isUpToDate,\n isError: shape.error !== false,\n shape,\n error: shape.error,\n }\n}\n\nconst identity = (arg: unknown) => arg\n\ninterface UseShapeOptions<Selection> extends ShapeStreamOptions {\n selector?: (value: UseShapeResult) => Selection\n}\n\nexport function useShape<Selection = UseShapeResult>({\n selector = identity as never,\n ...options\n}: UseShapeOptions<Selection>): Selection {\n const shapeStream = getShapeStream(options as ShapeStreamOptions)\n const shape = getShape(shapeStream)\n\n const latestShapeData = useRef(parseShapeData(shape))\n const getSnapshot = React.useCallback(() => latestShapeData.current, [])\n const shapeData = useSyncExternalStoreWithSelector(\n useCallback(\n (onStoreChange) =>\n shapeSubscribe(shape, () => {\n latestShapeData.current = parseShapeData(shape)\n onStoreChange()\n }),\n [shape]\n ),\n getSnapshot,\n getSnapshot,\n selector\n )\n\n return shapeData\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,oBAKO;AACP,mBAA2C;AAC3C,2BAAiD;AAEjD,IAAM,cAAc,oBAAI,IAAyB;AACjD,IAAM,aAAa,oBAAI,IAAwB;AAE/C,SAAsB,aACpB,SACgB;AAAA;AAChB,UAAM,cAAc,eAAe,OAAO;AAC1C,UAAM,QAAQ,SAAS,WAAW;AAClC,UAAM,MAAM;AACZ,WAAO;AAAA,EACT;AAAA;AAEO,SAAS,kBAAkB,SAAqC;AACrE,SAAO,KAAK,UAAU,SAAS,OAAO,KAAK,OAAO,EAAE,KAAK,CAAC;AAC5D;AAEO,SAAS,eAAe,SAA0C;AACvE,QAAM,YAAY,kBAAkB,OAAO;AAG3C,MAAI,YAAY,IAAI,SAAS,GAAG;AAE9B,WAAO,YAAY,IAAI,SAAS;AAAA,EAClC,OAAO;AACL,UAAM,iBAAiB,IAAI,0BAAY,OAAO;AAE9C,gBAAY,IAAI,WAAW,cAAc;AAGzC,WAAO;AAAA,EACT;AACF;AAEO,SAAS,SAAS,aAAiC;AAExD,MAAI,WAAW,IAAI,WAAW,GAAG;AAE/B,WAAO,WAAW,IAAI,WAAW;AAAA,EACnC,OAAO;AACL,UAAM,WAAW,IAAI,oBAAM,WAAW;AAEtC,eAAW,IAAI,aAAa,QAAQ;AAGpC,WAAO;AAAA,EACT;AACF;AAqBA,SAAS,eAAe,OAAc,UAAsB;AAC1D,QAAM,cAAc,MAAM,UAAU,QAAQ;AAC5C,SAAO,MAAM;AACX,gBAAY;AAAA,EACd;AACF;AAEA,SAAS,eAAe,OAA8B;AACpD,SAAO;AAAA,IACL,MAAM,CAAC,GAAG,MAAM,UAAU,OAAO,CAAC;AAAA,IAClC,YAAY,MAAM;AAAA,IAClB,SAAS,MAAM,UAAU;AAAA,IACzB;AAAA,IACA,OAAO,MAAM;AAAA,EACf;AACF;AAEA,IAAM,WAAW,CAAC,QAAiB;AAM5B,SAAS,SAAqC,IAGX;AAHW,eACnD;AAAA,eAAW;AAAA,EApGb,IAmGqD,IAEhD,oBAFgD,IAEhD;AAAA,IADH;AAAA;AAGA,QAAM,cAAc,eAAe,OAA6B;AAChE,QAAM,QAAQ,SAAS,WAAW;AAElC,QAAM,sBAAkB,qBAAO,eAAe,KAAK,CAAC;AACpD,QAAM,cAAc,aAAAA,QAAM,YAAY,MAAM,gBAAgB,SAAS,CAAC,CAAC;AACvE,QAAM,gBAAY;AAAA,QAChB;AAAA,MACE,CAAC,kBACC,eAAe,OAAO,MAAM;AAC1B,wBAAgB,UAAU,eAAe,KAAK;AAC9C,sBAAc;AAAA,MAChB,CAAC;AAAA,MACH,CAAC,KAAK;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SAAO;AACT;","names":["React"]}
|
package/dist/index.browser.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var u=Object.getOwnPropertySymbols;var
|
|
1
|
+
var u=Object.getOwnPropertySymbols;var g=Object.prototype.hasOwnProperty,U=Object.prototype.propertyIsEnumerable;var l=(e,t)=>{var a={};for(var r in e)g.call(e,r)&&t.indexOf(r)<0&&(a[r]=e[r]);if(e!=null&&u)for(var r of u(e))t.indexOf(r)<0&&U.call(e,r)&&(a[r]=e[r]);return a};var m=(e,t,a)=>new Promise((r,S)=>{var s=n=>{try{o(a.next(n))}catch(p){S(p)}},i=n=>{try{o(a.throw(n))}catch(p){S(p)}},o=n=>n.done?r(n.value):Promise.resolve(n.value).then(s,i);o((a=a.apply(e,t)).next())});import{Shape as w,ShapeStream as x}from"@electric-sql/client";import d,{useCallback as y,useRef as D}from"react";import{useSyncExternalStoreWithSelector as v}from"use-sync-external-store/with-selector.js";var c=new Map,h=new Map;function J(e){return m(this,null,function*(){let t=b(e),a=O(t);return yield a.value,a})}function R(e){return JSON.stringify(e,Object.keys(e).sort())}function b(e){let t=R(e);if(c.has(t))return c.get(t);{let a=new x(e);return c.set(t,a),a}}function O(e){if(h.has(e))return h.get(e);{let t=new w(e);return h.set(e,t),t}}function k(e,t){let a=e.subscribe(t);return()=>{a()}}function f(e){return{data:[...e.valueSync.values()],isUpToDate:e.isUpToDate,isError:e.error!==!1,shape:e,error:e.error}}var C=e=>e;function N(a){var r=a,{selector:e=C}=r,t=l(r,["selector"]);let S=b(t),s=O(S),i=D(f(s)),o=d.useCallback(()=>i.current,[]);return v(y(p=>k(s,()=>{i.current=f(s),p()}),[s]),o,o,e)}export{O as getShape,b as getShapeStream,J as preloadShape,R as sortedOptionsHash,N as useShape};
|
|
2
2
|
//# sourceMappingURL=index.browser.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/react-hooks.tsx"],"sourcesContent":["import {\n Value,\n Shape,\n ShapeStream,\n ShapeStreamOptions,\n} from '@electric-sql/client'\nimport React, {
|
|
1
|
+
{"version":3,"sources":["../src/react-hooks.tsx"],"sourcesContent":["import {\n Value,\n Shape,\n ShapeStream,\n ShapeStreamOptions,\n} from '@electric-sql/client'\nimport React, { useCallback, useRef } from 'react'\nimport { useSyncExternalStoreWithSelector } from 'use-sync-external-store/with-selector.js'\n\nconst streamCache = new Map<string, ShapeStream>()\nconst shapeCache = new Map<ShapeStream, Shape>()\n\nexport async function preloadShape(\n options: ShapeStreamOptions\n): Promise<Shape> {\n const shapeStream = getShapeStream(options)\n const shape = getShape(shapeStream)\n await shape.value\n return shape\n}\n\nexport function sortedOptionsHash(options: ShapeStreamOptions): string {\n return JSON.stringify(options, Object.keys(options).sort())\n}\n\nexport function getShapeStream(options: ShapeStreamOptions): ShapeStream {\n const shapeHash = sortedOptionsHash(options)\n\n // If the stream is already cached, return\n if (streamCache.has(shapeHash)) {\n // Return the ShapeStream\n return streamCache.get(shapeHash)!\n } else {\n const newShapeStream = new ShapeStream(options)\n\n streamCache.set(shapeHash, newShapeStream)\n\n // Return the created shape\n return newShapeStream\n }\n}\n\nexport function getShape(shapeStream: ShapeStream): Shape {\n // If the stream is already cached, return\n if (shapeCache.has(shapeStream)) {\n // Return the ShapeStream\n return shapeCache.get(shapeStream)!\n } else {\n const newShape = new Shape(shapeStream)\n\n shapeCache.set(shapeStream, newShape)\n\n // Return the created shape\n return newShape\n }\n}\n\ninterface UseShapeResult {\n /**\n * The array of rows that make up the Shape.\n * @type {{ [key: string]: Value }[]}\n */\n data: { [key: string]: Value }[]\n /**\n * The Shape instance used by this useShape\n * @type(Shape)\n */\n shape: Shape\n error: Shape[`error`]\n isError: boolean\n /**\n * Has the ShapeStream caught up with the replication log from Postgres.\n */\n isUpToDate: boolean\n}\n\nfunction shapeSubscribe(shape: Shape, callback: () => void) {\n const unsubscribe = shape.subscribe(callback)\n return () => {\n unsubscribe()\n }\n}\n\nfunction parseShapeData(shape: Shape): UseShapeResult {\n return {\n data: [...shape.valueSync.values()],\n isUpToDate: shape.isUpToDate,\n isError: shape.error !== false,\n shape,\n error: shape.error,\n }\n}\n\nconst identity = (arg: unknown) => arg\n\ninterface UseShapeOptions<Selection> extends ShapeStreamOptions {\n selector?: (value: UseShapeResult) => Selection\n}\n\nexport function useShape<Selection = UseShapeResult>({\n selector = identity as never,\n ...options\n}: UseShapeOptions<Selection>): Selection {\n const shapeStream = getShapeStream(options as ShapeStreamOptions)\n const shape = getShape(shapeStream)\n\n const latestShapeData = useRef(parseShapeData(shape))\n const getSnapshot = React.useCallback(() => latestShapeData.current, [])\n const shapeData = useSyncExternalStoreWithSelector(\n useCallback(\n (onStoreChange) =>\n shapeSubscribe(shape, () => {\n latestShapeData.current = parseShapeData(shape)\n onStoreChange()\n }),\n [shape]\n ),\n getSnapshot,\n getSnapshot,\n selector\n )\n\n return shapeData\n}\n"],"mappings":"geAAA,OAEE,SAAAA,EACA,eAAAC,MAEK,uBACP,OAAOC,GAAS,eAAAC,EAAa,UAAAC,MAAc,QAC3C,OAAS,oCAAAC,MAAwC,2CAEjD,IAAMC,EAAc,IAAI,IAClBC,EAAa,IAAI,IAEvB,SAAsBC,EACpBC,EACgB,QAAAC,EAAA,sBAChB,IAAMC,EAAcC,EAAeH,CAAO,EACpCI,EAAQC,EAASH,CAAW,EAClC,aAAME,EAAM,MACLA,CACT,GAEO,SAASE,EAAkBN,EAAqC,CACrE,OAAO,KAAK,UAAUA,EAAS,OAAO,KAAKA,CAAO,EAAE,KAAK,CAAC,CAC5D,CAEO,SAASG,EAAeH,EAA0C,CACvE,IAAMO,EAAYD,EAAkBN,CAAO,EAG3C,GAAIH,EAAY,IAAIU,CAAS,EAE3B,OAAOV,EAAY,IAAIU,CAAS,EAC3B,CACL,IAAMC,EAAiB,IAAIC,EAAYT,CAAO,EAE9C,OAAAH,EAAY,IAAIU,EAAWC,CAAc,EAGlCA,CACT,CACF,CAEO,SAASH,EAASH,EAAiC,CAExD,GAAIJ,EAAW,IAAII,CAAW,EAE5B,OAAOJ,EAAW,IAAII,CAAW,EAC5B,CACL,IAAMQ,EAAW,IAAIC,EAAMT,CAAW,EAEtC,OAAAJ,EAAW,IAAII,EAAaQ,CAAQ,EAG7BA,CACT,CACF,CAqBA,SAASE,EAAeR,EAAcS,EAAsB,CAC1D,IAAMC,EAAcV,EAAM,UAAUS,CAAQ,EAC5C,MAAO,IAAM,CACXC,EAAY,CACd,CACF,CAEA,SAASC,EAAeX,EAA8B,CACpD,MAAO,CACL,KAAM,CAAC,GAAGA,EAAM,UAAU,OAAO,CAAC,EAClC,WAAYA,EAAM,WAClB,QAASA,EAAM,QAAU,GACzB,MAAAA,EACA,MAAOA,EAAM,KACf,CACF,CAEA,IAAMY,EAAYC,GAAiBA,EAM5B,SAASC,EAAqCC,EAGX,CAHW,IAAAC,EAAAD,EACnD,UAAAE,EAAWL,CApGb,EAmGqDI,EAEhDpB,EAAAsB,EAFgDF,EAEhD,CADH,aAGA,IAAMlB,EAAcC,EAAeH,CAA6B,EAC1DI,EAAQC,EAASH,CAAW,EAE5BqB,EAAkBC,EAAOT,EAAeX,CAAK,CAAC,EAC9CqB,EAAcC,EAAM,YAAY,IAAMH,EAAgB,QAAS,CAAC,CAAC,EAevE,OAdkBI,EAChBC,EACGC,GACCjB,EAAeR,EAAO,IAAM,CAC1BmB,EAAgB,QAAUR,EAAeX,CAAK,EAC9CyB,EAAc,CAChB,CAAC,EACH,CAACzB,CAAK,CACR,EACAqB,EACAA,EACAJ,CACF,CAGF","names":["Shape","ShapeStream","React","useCallback","useRef","useSyncExternalStoreWithSelector","streamCache","shapeCache","preloadShape","options","__async","shapeStream","getShapeStream","shape","getShape","sortedOptionsHash","shapeHash","newShapeStream","ShapeStream","newShape","Shape","shapeSubscribe","callback","unsubscribe","parseShapeData","identity","arg","useShape","_a","_b","selector","__objRest","latestShapeData","useRef","getSnapshot","React","useSyncExternalStoreWithSelector","useCallback","onStoreChange"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,19 +1,9 @@
|
|
|
1
1
|
import { ShapeStreamOptions, Shape, ShapeStream, Value } from '@electric-sql/client';
|
|
2
|
-
import React from 'react';
|
|
3
2
|
|
|
4
|
-
interface ShapeContextType {
|
|
5
|
-
getShape: (shapeStream: ShapeStream) => Shape;
|
|
6
|
-
getShapeStream: (options: ShapeStreamOptions) => ShapeStream;
|
|
7
|
-
}
|
|
8
3
|
declare function preloadShape(options: ShapeStreamOptions): Promise<Shape>;
|
|
9
4
|
declare function sortedOptionsHash(options: ShapeStreamOptions): string;
|
|
10
5
|
declare function getShapeStream(options: ShapeStreamOptions): ShapeStream;
|
|
11
6
|
declare function getShape(shapeStream: ShapeStream): Shape;
|
|
12
|
-
interface ShapeProviderProps {
|
|
13
|
-
children: React.ReactNode;
|
|
14
|
-
}
|
|
15
|
-
declare function ShapesProvider({ children }: ShapeProviderProps): JSX.Element;
|
|
16
|
-
declare function useShapeContext(): ShapeContextType;
|
|
17
7
|
interface UseShapeResult {
|
|
18
8
|
/**
|
|
19
9
|
* The array of rows that make up the Shape.
|
|
@@ -39,4 +29,4 @@ interface UseShapeOptions<Selection> extends ShapeStreamOptions {
|
|
|
39
29
|
}
|
|
40
30
|
declare function useShape<Selection = UseShapeResult>({ selector, ...options }: UseShapeOptions<Selection>): Selection;
|
|
41
31
|
|
|
42
|
-
export {
|
|
32
|
+
export { getShape, getShapeStream, preloadShape, sortedOptionsHash, useShape };
|
package/dist/index.legacy-esm.js
CHANGED
|
@@ -19,9 +19,8 @@ import {
|
|
|
19
19
|
Shape,
|
|
20
20
|
ShapeStream
|
|
21
21
|
} from "@electric-sql/client";
|
|
22
|
-
import React, {
|
|
22
|
+
import React, { useCallback, useRef } from "react";
|
|
23
23
|
import { useSyncExternalStoreWithSelector } from "use-sync-external-store/with-selector.js";
|
|
24
|
-
var ShapesContext = createContext(null);
|
|
25
24
|
var streamCache = /* @__PURE__ */ new Map();
|
|
26
25
|
var shapeCache = /* @__PURE__ */ new Map();
|
|
27
26
|
async function preloadShape(options) {
|
|
@@ -52,16 +51,6 @@ function getShape(shapeStream) {
|
|
|
52
51
|
return newShape;
|
|
53
52
|
}
|
|
54
53
|
}
|
|
55
|
-
function ShapesProvider({ children }) {
|
|
56
|
-
return /* @__PURE__ */ React.createElement(ShapesContext.Provider, { value: { getShape, getShapeStream } }, children);
|
|
57
|
-
}
|
|
58
|
-
function useShapeContext() {
|
|
59
|
-
const context = useContext(ShapesContext);
|
|
60
|
-
if (!context) {
|
|
61
|
-
throw new Error(`useShapeContext must be used within a ShapeProvider`);
|
|
62
|
-
}
|
|
63
|
-
return context;
|
|
64
|
-
}
|
|
65
54
|
function shapeSubscribe(shape, callback) {
|
|
66
55
|
const unsubscribe = shape.subscribe(callback);
|
|
67
56
|
return () => {
|
|
@@ -84,9 +73,8 @@ function useShape(_a) {
|
|
|
84
73
|
} = _b, options = __objRest(_b, [
|
|
85
74
|
"selector"
|
|
86
75
|
]);
|
|
87
|
-
const
|
|
88
|
-
const
|
|
89
|
-
const shape = getShape2(shapeStream);
|
|
76
|
+
const shapeStream = getShapeStream(options);
|
|
77
|
+
const shape = getShape(shapeStream);
|
|
90
78
|
const latestShapeData = useRef(parseShapeData(shape));
|
|
91
79
|
const getSnapshot = React.useCallback(() => latestShapeData.current, []);
|
|
92
80
|
const shapeData = useSyncExternalStoreWithSelector(
|
|
@@ -104,12 +92,10 @@ function useShape(_a) {
|
|
|
104
92
|
return shapeData;
|
|
105
93
|
}
|
|
106
94
|
export {
|
|
107
|
-
ShapesProvider,
|
|
108
95
|
getShape,
|
|
109
96
|
getShapeStream,
|
|
110
97
|
preloadShape,
|
|
111
98
|
sortedOptionsHash,
|
|
112
|
-
useShape
|
|
113
|
-
useShapeContext
|
|
99
|
+
useShape
|
|
114
100
|
};
|
|
115
101
|
//# sourceMappingURL=index.legacy-esm.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/react-hooks.tsx"],"sourcesContent":["import {\n Value,\n Shape,\n ShapeStream,\n ShapeStreamOptions,\n} from '@electric-sql/client'\nimport React, {
|
|
1
|
+
{"version":3,"sources":["../src/react-hooks.tsx"],"sourcesContent":["import {\n Value,\n Shape,\n ShapeStream,\n ShapeStreamOptions,\n} from '@electric-sql/client'\nimport React, { useCallback, useRef } from 'react'\nimport { useSyncExternalStoreWithSelector } from 'use-sync-external-store/with-selector.js'\n\nconst streamCache = new Map<string, ShapeStream>()\nconst shapeCache = new Map<ShapeStream, Shape>()\n\nexport async function preloadShape(\n options: ShapeStreamOptions\n): Promise<Shape> {\n const shapeStream = getShapeStream(options)\n const shape = getShape(shapeStream)\n await shape.value\n return shape\n}\n\nexport function sortedOptionsHash(options: ShapeStreamOptions): string {\n return JSON.stringify(options, Object.keys(options).sort())\n}\n\nexport function getShapeStream(options: ShapeStreamOptions): ShapeStream {\n const shapeHash = sortedOptionsHash(options)\n\n // If the stream is already cached, return\n if (streamCache.has(shapeHash)) {\n // Return the ShapeStream\n return streamCache.get(shapeHash)!\n } else {\n const newShapeStream = new ShapeStream(options)\n\n streamCache.set(shapeHash, newShapeStream)\n\n // Return the created shape\n return newShapeStream\n }\n}\n\nexport function getShape(shapeStream: ShapeStream): Shape {\n // If the stream is already cached, return\n if (shapeCache.has(shapeStream)) {\n // Return the ShapeStream\n return shapeCache.get(shapeStream)!\n } else {\n const newShape = new Shape(shapeStream)\n\n shapeCache.set(shapeStream, newShape)\n\n // Return the created shape\n return newShape\n }\n}\n\ninterface UseShapeResult {\n /**\n * The array of rows that make up the Shape.\n * @type {{ [key: string]: Value }[]}\n */\n data: { [key: string]: Value }[]\n /**\n * The Shape instance used by this useShape\n * @type(Shape)\n */\n shape: Shape\n error: Shape[`error`]\n isError: boolean\n /**\n * Has the ShapeStream caught up with the replication log from Postgres.\n */\n isUpToDate: boolean\n}\n\nfunction shapeSubscribe(shape: Shape, callback: () => void) {\n const unsubscribe = shape.subscribe(callback)\n return () => {\n unsubscribe()\n }\n}\n\nfunction parseShapeData(shape: Shape): UseShapeResult {\n return {\n data: [...shape.valueSync.values()],\n isUpToDate: shape.isUpToDate,\n isError: shape.error !== false,\n shape,\n error: shape.error,\n }\n}\n\nconst identity = (arg: unknown) => arg\n\ninterface UseShapeOptions<Selection> extends ShapeStreamOptions {\n selector?: (value: UseShapeResult) => Selection\n}\n\nexport function useShape<Selection = UseShapeResult>({\n selector = identity as never,\n ...options\n}: UseShapeOptions<Selection>): Selection {\n const shapeStream = getShapeStream(options as ShapeStreamOptions)\n const shape = getShape(shapeStream)\n\n const latestShapeData = useRef(parseShapeData(shape))\n const getSnapshot = React.useCallback(() => latestShapeData.current, [])\n const shapeData = useSyncExternalStoreWithSelector(\n useCallback(\n (onStoreChange) =>\n shapeSubscribe(shape, () => {\n latestShapeData.current = parseShapeData(shape)\n onStoreChange()\n }),\n [shape]\n ),\n getSnapshot,\n getSnapshot,\n selector\n )\n\n return shapeData\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAAA;AAAA,EAEE;AAAA,EACA;AAAA,OAEK;AACP,OAAO,SAAS,aAAa,cAAc;AAC3C,SAAS,wCAAwC;AAEjD,IAAM,cAAc,oBAAI,IAAyB;AACjD,IAAM,aAAa,oBAAI,IAAwB;AAE/C,eAAsB,aACpB,SACgB;AAChB,QAAM,cAAc,eAAe,OAAO;AAC1C,QAAM,QAAQ,SAAS,WAAW;AAClC,QAAM,MAAM;AACZ,SAAO;AACT;AAEO,SAAS,kBAAkB,SAAqC;AACrE,SAAO,KAAK,UAAU,SAAS,OAAO,KAAK,OAAO,EAAE,KAAK,CAAC;AAC5D;AAEO,SAAS,eAAe,SAA0C;AACvE,QAAM,YAAY,kBAAkB,OAAO;AAG3C,MAAI,YAAY,IAAI,SAAS,GAAG;AAE9B,WAAO,YAAY,IAAI,SAAS;AAAA,EAClC,OAAO;AACL,UAAM,iBAAiB,IAAI,YAAY,OAAO;AAE9C,gBAAY,IAAI,WAAW,cAAc;AAGzC,WAAO;AAAA,EACT;AACF;AAEO,SAAS,SAAS,aAAiC;AAExD,MAAI,WAAW,IAAI,WAAW,GAAG;AAE/B,WAAO,WAAW,IAAI,WAAW;AAAA,EACnC,OAAO;AACL,UAAM,WAAW,IAAI,MAAM,WAAW;AAEtC,eAAW,IAAI,aAAa,QAAQ;AAGpC,WAAO;AAAA,EACT;AACF;AAqBA,SAAS,eAAe,OAAc,UAAsB;AAC1D,QAAM,cAAc,MAAM,UAAU,QAAQ;AAC5C,SAAO,MAAM;AACX,gBAAY;AAAA,EACd;AACF;AAEA,SAAS,eAAe,OAA8B;AACpD,SAAO;AAAA,IACL,MAAM,CAAC,GAAG,MAAM,UAAU,OAAO,CAAC;AAAA,IAClC,YAAY,MAAM;AAAA,IAClB,SAAS,MAAM,UAAU;AAAA,IACzB;AAAA,IACA,OAAO,MAAM;AAAA,EACf;AACF;AAEA,IAAM,WAAW,CAAC,QAAiB;AAM5B,SAAS,SAAqC,IAGX;AAHW,eACnD;AAAA,eAAW;AAAA,EApGb,IAmGqD,IAEhD,oBAFgD,IAEhD;AAAA,IADH;AAAA;AAGA,QAAM,cAAc,eAAe,OAA6B;AAChE,QAAM,QAAQ,SAAS,WAAW;AAElC,QAAM,kBAAkB,OAAO,eAAe,KAAK,CAAC;AACpD,QAAM,cAAc,MAAM,YAAY,MAAM,gBAAgB,SAAS,CAAC,CAAC;AACvE,QAAM,YAAY;AAAA,IAChB;AAAA,MACE,CAAC,kBACC,eAAe,OAAO,MAAM;AAC1B,wBAAgB,UAAU,eAAe,KAAK;AAC9C,sBAAc;AAAA,MAChB,CAAC;AAAA,MACH,CAAC,KAAK;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SAAO;AACT;","names":[]}
|
package/dist/index.mjs
CHANGED
|
@@ -39,9 +39,8 @@ import {
|
|
|
39
39
|
Shape,
|
|
40
40
|
ShapeStream
|
|
41
41
|
} from "@electric-sql/client";
|
|
42
|
-
import React, {
|
|
42
|
+
import React, { useCallback, useRef } from "react";
|
|
43
43
|
import { useSyncExternalStoreWithSelector } from "use-sync-external-store/with-selector.js";
|
|
44
|
-
var ShapesContext = createContext(null);
|
|
45
44
|
var streamCache = /* @__PURE__ */ new Map();
|
|
46
45
|
var shapeCache = /* @__PURE__ */ new Map();
|
|
47
46
|
function preloadShape(options) {
|
|
@@ -74,16 +73,6 @@ function getShape(shapeStream) {
|
|
|
74
73
|
return newShape;
|
|
75
74
|
}
|
|
76
75
|
}
|
|
77
|
-
function ShapesProvider({ children }) {
|
|
78
|
-
return /* @__PURE__ */ React.createElement(ShapesContext.Provider, { value: { getShape, getShapeStream } }, children);
|
|
79
|
-
}
|
|
80
|
-
function useShapeContext() {
|
|
81
|
-
const context = useContext(ShapesContext);
|
|
82
|
-
if (!context) {
|
|
83
|
-
throw new Error(`useShapeContext must be used within a ShapeProvider`);
|
|
84
|
-
}
|
|
85
|
-
return context;
|
|
86
|
-
}
|
|
87
76
|
function shapeSubscribe(shape, callback) {
|
|
88
77
|
const unsubscribe = shape.subscribe(callback);
|
|
89
78
|
return () => {
|
|
@@ -106,9 +95,8 @@ function useShape(_a) {
|
|
|
106
95
|
} = _b, options = __objRest(_b, [
|
|
107
96
|
"selector"
|
|
108
97
|
]);
|
|
109
|
-
const
|
|
110
|
-
const
|
|
111
|
-
const shape = getShape2(shapeStream);
|
|
98
|
+
const shapeStream = getShapeStream(options);
|
|
99
|
+
const shape = getShape(shapeStream);
|
|
112
100
|
const latestShapeData = useRef(parseShapeData(shape));
|
|
113
101
|
const getSnapshot = React.useCallback(() => latestShapeData.current, []);
|
|
114
102
|
const shapeData = useSyncExternalStoreWithSelector(
|
|
@@ -126,12 +114,10 @@ function useShape(_a) {
|
|
|
126
114
|
return shapeData;
|
|
127
115
|
}
|
|
128
116
|
export {
|
|
129
|
-
ShapesProvider,
|
|
130
117
|
getShape,
|
|
131
118
|
getShapeStream,
|
|
132
119
|
preloadShape,
|
|
133
120
|
sortedOptionsHash,
|
|
134
|
-
useShape
|
|
135
|
-
useShapeContext
|
|
121
|
+
useShape
|
|
136
122
|
};
|
|
137
123
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/react-hooks.tsx"],"sourcesContent":["import {\n Value,\n Shape,\n ShapeStream,\n ShapeStreamOptions,\n} from '@electric-sql/client'\nimport React, {
|
|
1
|
+
{"version":3,"sources":["../src/react-hooks.tsx"],"sourcesContent":["import {\n Value,\n Shape,\n ShapeStream,\n ShapeStreamOptions,\n} from '@electric-sql/client'\nimport React, { useCallback, useRef } from 'react'\nimport { useSyncExternalStoreWithSelector } from 'use-sync-external-store/with-selector.js'\n\nconst streamCache = new Map<string, ShapeStream>()\nconst shapeCache = new Map<ShapeStream, Shape>()\n\nexport async function preloadShape(\n options: ShapeStreamOptions\n): Promise<Shape> {\n const shapeStream = getShapeStream(options)\n const shape = getShape(shapeStream)\n await shape.value\n return shape\n}\n\nexport function sortedOptionsHash(options: ShapeStreamOptions): string {\n return JSON.stringify(options, Object.keys(options).sort())\n}\n\nexport function getShapeStream(options: ShapeStreamOptions): ShapeStream {\n const shapeHash = sortedOptionsHash(options)\n\n // If the stream is already cached, return\n if (streamCache.has(shapeHash)) {\n // Return the ShapeStream\n return streamCache.get(shapeHash)!\n } else {\n const newShapeStream = new ShapeStream(options)\n\n streamCache.set(shapeHash, newShapeStream)\n\n // Return the created shape\n return newShapeStream\n }\n}\n\nexport function getShape(shapeStream: ShapeStream): Shape {\n // If the stream is already cached, return\n if (shapeCache.has(shapeStream)) {\n // Return the ShapeStream\n return shapeCache.get(shapeStream)!\n } else {\n const newShape = new Shape(shapeStream)\n\n shapeCache.set(shapeStream, newShape)\n\n // Return the created shape\n return newShape\n }\n}\n\ninterface UseShapeResult {\n /**\n * The array of rows that make up the Shape.\n * @type {{ [key: string]: Value }[]}\n */\n data: { [key: string]: Value }[]\n /**\n * The Shape instance used by this useShape\n * @type(Shape)\n */\n shape: Shape\n error: Shape[`error`]\n isError: boolean\n /**\n * Has the ShapeStream caught up with the replication log from Postgres.\n */\n isUpToDate: boolean\n}\n\nfunction shapeSubscribe(shape: Shape, callback: () => void) {\n const unsubscribe = shape.subscribe(callback)\n return () => {\n unsubscribe()\n }\n}\n\nfunction parseShapeData(shape: Shape): UseShapeResult {\n return {\n data: [...shape.valueSync.values()],\n isUpToDate: shape.isUpToDate,\n isError: shape.error !== false,\n shape,\n error: shape.error,\n }\n}\n\nconst identity = (arg: unknown) => arg\n\ninterface UseShapeOptions<Selection> extends ShapeStreamOptions {\n selector?: (value: UseShapeResult) => Selection\n}\n\nexport function useShape<Selection = UseShapeResult>({\n selector = identity as never,\n ...options\n}: UseShapeOptions<Selection>): Selection {\n const shapeStream = getShapeStream(options as ShapeStreamOptions)\n const shape = getShape(shapeStream)\n\n const latestShapeData = useRef(parseShapeData(shape))\n const getSnapshot = React.useCallback(() => latestShapeData.current, [])\n const shapeData = useSyncExternalStoreWithSelector(\n useCallback(\n (onStoreChange) =>\n shapeSubscribe(shape, () => {\n latestShapeData.current = parseShapeData(shape)\n onStoreChange()\n }),\n [shape]\n ),\n getSnapshot,\n getSnapshot,\n selector\n )\n\n return shapeData\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA,EAEE;AAAA,EACA;AAAA,OAEK;AACP,OAAO,SAAS,aAAa,cAAc;AAC3C,SAAS,wCAAwC;AAEjD,IAAM,cAAc,oBAAI,IAAyB;AACjD,IAAM,aAAa,oBAAI,IAAwB;AAE/C,SAAsB,aACpB,SACgB;AAAA;AAChB,UAAM,cAAc,eAAe,OAAO;AAC1C,UAAM,QAAQ,SAAS,WAAW;AAClC,UAAM,MAAM;AACZ,WAAO;AAAA,EACT;AAAA;AAEO,SAAS,kBAAkB,SAAqC;AACrE,SAAO,KAAK,UAAU,SAAS,OAAO,KAAK,OAAO,EAAE,KAAK,CAAC;AAC5D;AAEO,SAAS,eAAe,SAA0C;AACvE,QAAM,YAAY,kBAAkB,OAAO;AAG3C,MAAI,YAAY,IAAI,SAAS,GAAG;AAE9B,WAAO,YAAY,IAAI,SAAS;AAAA,EAClC,OAAO;AACL,UAAM,iBAAiB,IAAI,YAAY,OAAO;AAE9C,gBAAY,IAAI,WAAW,cAAc;AAGzC,WAAO;AAAA,EACT;AACF;AAEO,SAAS,SAAS,aAAiC;AAExD,MAAI,WAAW,IAAI,WAAW,GAAG;AAE/B,WAAO,WAAW,IAAI,WAAW;AAAA,EACnC,OAAO;AACL,UAAM,WAAW,IAAI,MAAM,WAAW;AAEtC,eAAW,IAAI,aAAa,QAAQ;AAGpC,WAAO;AAAA,EACT;AACF;AAqBA,SAAS,eAAe,OAAc,UAAsB;AAC1D,QAAM,cAAc,MAAM,UAAU,QAAQ;AAC5C,SAAO,MAAM;AACX,gBAAY;AAAA,EACd;AACF;AAEA,SAAS,eAAe,OAA8B;AACpD,SAAO;AAAA,IACL,MAAM,CAAC,GAAG,MAAM,UAAU,OAAO,CAAC;AAAA,IAClC,YAAY,MAAM;AAAA,IAClB,SAAS,MAAM,UAAU;AAAA,IACzB;AAAA,IACA,OAAO,MAAM;AAAA,EACf;AACF;AAEA,IAAM,WAAW,CAAC,QAAiB;AAM5B,SAAS,SAAqC,IAGX;AAHW,eACnD;AAAA,eAAW;AAAA,EApGb,IAmGqD,IAEhD,oBAFgD,IAEhD;AAAA,IADH;AAAA;AAGA,QAAM,cAAc,eAAe,OAA6B;AAChE,QAAM,QAAQ,SAAS,WAAW;AAElC,QAAM,kBAAkB,OAAO,eAAe,KAAK,CAAC;AACpD,QAAM,cAAc,MAAM,YAAY,MAAM,gBAAgB,SAAS,CAAC,CAAC;AACvE,QAAM,YAAY;AAAA,IAChB;AAAA,MACE,CAAC,kBACC,eAAe,OAAO,MAAM;AAC1B,wBAAgB,UAAU,eAAe,KAAK;AAC9C,sBAAc;AAAA,MAChB,CAAC;AAAA,MACH,CAAC,KAAK;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SAAO;AACT;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@electric-sql/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "React hooks for ElectricSQL",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/cjs/index.cjs",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"homepage": "https://next.electric-sql.com",
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"use-sync-external-store": "^1.2.2",
|
|
34
|
-
"@electric-sql/client": "0.3.
|
|
34
|
+
"@electric-sql/client": "0.3.2"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@testing-library/react": "^16.0.0",
|
package/src/react-hooks.tsx
CHANGED
|
@@ -4,17 +4,9 @@ import {
|
|
|
4
4
|
ShapeStream,
|
|
5
5
|
ShapeStreamOptions,
|
|
6
6
|
} from '@electric-sql/client'
|
|
7
|
-
import React, {
|
|
7
|
+
import React, { useCallback, useRef } from 'react'
|
|
8
8
|
import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/with-selector.js'
|
|
9
9
|
|
|
10
|
-
interface ShapeContextType {
|
|
11
|
-
getShape: (shapeStream: ShapeStream) => Shape
|
|
12
|
-
getShapeStream: (options: ShapeStreamOptions) => ShapeStream
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
// Create a Context
|
|
16
|
-
const ShapesContext = createContext<ShapeContextType | null>(null)
|
|
17
|
-
|
|
18
10
|
const streamCache = new Map<string, ShapeStream>()
|
|
19
11
|
const shapeCache = new Map<ShapeStream, Shape>()
|
|
20
12
|
|
|
@@ -63,28 +55,6 @@ export function getShape(shapeStream: ShapeStream): Shape {
|
|
|
63
55
|
}
|
|
64
56
|
}
|
|
65
57
|
|
|
66
|
-
interface ShapeProviderProps {
|
|
67
|
-
children: React.ReactNode
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Shapes Provider Component
|
|
71
|
-
export function ShapesProvider({ children }: ShapeProviderProps): JSX.Element {
|
|
72
|
-
// Provide the context value
|
|
73
|
-
return (
|
|
74
|
-
<ShapesContext.Provider value={{ getShape, getShapeStream }}>
|
|
75
|
-
{children}
|
|
76
|
-
</ShapesContext.Provider>
|
|
77
|
-
)
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export function useShapeContext() {
|
|
81
|
-
const context = useContext(ShapesContext)
|
|
82
|
-
if (!context) {
|
|
83
|
-
throw new Error(`useShapeContext must be used within a ShapeProvider`)
|
|
84
|
-
}
|
|
85
|
-
return context
|
|
86
|
-
}
|
|
87
|
-
|
|
88
58
|
interface UseShapeResult {
|
|
89
59
|
/**
|
|
90
60
|
* The array of rows that make up the Shape.
|
|
@@ -131,7 +101,6 @@ export function useShape<Selection = UseShapeResult>({
|
|
|
131
101
|
selector = identity as never,
|
|
132
102
|
...options
|
|
133
103
|
}: UseShapeOptions<Selection>): Selection {
|
|
134
|
-
const { getShape, getShapeStream } = useShapeContext()
|
|
135
104
|
const shapeStream = getShapeStream(options as ShapeStreamOptions)
|
|
136
105
|
const shape = getShape(shapeStream)
|
|
137
106
|
|