@electric-sql/react 1.0.22 → 1.0.24

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.
@@ -40,26 +40,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
40
40
  mod
41
41
  ));
42
42
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
43
- var __async = (__this, __arguments, generator) => {
44
- return new Promise((resolve, reject) => {
45
- var fulfilled = (value) => {
46
- try {
47
- step(generator.next(value));
48
- } catch (e) {
49
- reject(e);
50
- }
51
- };
52
- var rejected = (value) => {
53
- try {
54
- step(generator.throw(value));
55
- } catch (e) {
56
- reject(e);
57
- }
58
- };
59
- var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
60
- step((generator = generator.apply(__this, __arguments)).next());
61
- });
62
- };
63
43
 
64
44
  // src/index.ts
65
45
  var src_exports = {};
@@ -78,13 +58,11 @@ var import_react = __toESM(require("react"), 1);
78
58
  var import_with_selector = require("use-sync-external-store/with-selector.js");
79
59
  var streamCache = /* @__PURE__ */ new Map();
80
60
  var shapeCache = /* @__PURE__ */ new Map();
81
- function preloadShape(options) {
82
- return __async(this, null, function* () {
83
- const shapeStream = getShapeStream(options);
84
- const shape = getShape(shapeStream);
85
- yield shape.rows;
86
- return shape;
87
- });
61
+ async function preloadShape(options) {
62
+ const shapeStream = getShapeStream(options);
63
+ const shape = getShape(shapeStream);
64
+ await shape.rows;
65
+ return shape;
88
66
  }
89
67
  function sortObjectKeys(obj) {
90
68
  if (typeof obj === `function`) return Function.prototype.toString.call(obj);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts","../../src/react-hooks.tsx"],"sourcesContent":["export * from './react-hooks'\n","import {\n Shape,\n ShapeStream,\n ShapeStreamOptions,\n Row,\n GetExtensions,\n} from '@electric-sql/client'\nimport React from 'react'\nimport { useSyncExternalStoreWithSelector } from 'use-sync-external-store/with-selector.js'\n\ntype UnknownShape = Shape<Row<unknown>>\ntype UnknownShapeStream = ShapeStream<Row<unknown>>\n\nconst streamCache = new Map<string, UnknownShapeStream>()\nconst shapeCache = new Map<UnknownShapeStream, UnknownShape>()\n\nexport async function preloadShape<T extends Row<unknown> = Row>(\n options: ShapeStreamOptions<GetExtensions<T>>\n): Promise<Shape<T>> {\n const shapeStream = getShapeStream<T>(options)\n const shape = getShape<T>(shapeStream)\n await shape.rows\n return shape\n}\n\nfunction sortObjectKeys(obj: any): any {\n if (typeof obj === `function`) return Function.prototype.toString.call(obj)\n if (typeof obj !== `object` || obj === null) return obj\n\n if (Array.isArray(obj)) {\n return obj.map(sortObjectKeys)\n }\n\n return Object.keys(obj)\n .sort()\n\n .reduce<Record<string, any>>((sorted, key) => {\n sorted[key] = sortObjectKeys(obj[key])\n return sorted\n }, {})\n}\n\nexport function sortedOptionsHash<T>(options: ShapeStreamOptions<T>): string {\n return JSON.stringify(sortObjectKeys(options))\n}\n\nexport function getShapeStream<T extends Row<unknown>>(\n options: ShapeStreamOptions<GetExtensions<T>>\n): ShapeStream<T> {\n const shapeHash = sortedOptionsHash(options)\n\n // If the stream is already cached, return it if valid\n if (streamCache.has(shapeHash)) {\n const stream = streamCache.get(shapeHash)! as ShapeStream<T>\n if (!stream.options.signal?.aborted) {\n return stream\n }\n\n // if stream is aborted, remove it and related shapes\n streamCache.delete(shapeHash)\n shapeCache.delete(stream)\n }\n\n const newShapeStream = new ShapeStream<T>(options)\n streamCache.set(shapeHash, newShapeStream)\n\n // Return the created shape\n return newShapeStream\n}\n\nexport function getShape<T extends Row<unknown>>(\n shapeStream: ShapeStream<T>\n): Shape<T> {\n // If the stream is already cached, return it if valid\n if (shapeCache.has(shapeStream)) {\n if (!shapeStream.options.signal?.aborted) {\n return shapeCache.get(shapeStream)! as Shape<T>\n }\n\n // if stream is aborted, remove it and related shapes\n streamCache.delete(sortedOptionsHash(shapeStream.options))\n shapeCache.delete(shapeStream)\n }\n\n const newShape = new Shape<T>(shapeStream)\n shapeCache.set(shapeStream, newShape)\n\n // Return the created shape\n return newShape\n}\n\nexport interface UseShapeResult<T extends Row<unknown> = Row> {\n /**\n * The array of rows that make up the Shape.\n * @type {T[]}\n */\n data: T[]\n /**\n * The Shape instance used by this useShape\n * @type {Shape<T>}\n */\n shape: Shape<T>\n /**\n * The ShapeStream instance used by this Shape\n * @type {ShapeStream<T>}\n */\n stream: ShapeStream<T>\n /** True during initial fetch. False afterwise. */\n isLoading: boolean\n /** Unix time at which we last synced. Undefined when `isLoading` is true. */\n lastSyncedAt?: number\n error: Shape<T>[`error`]\n isError: boolean\n}\n\nfunction shapeSubscribe<T extends Row<unknown>>(\n shape: Shape<T>,\n callback: () => void\n) {\n const unsubscribe = shape.subscribe(callback)\n return () => {\n unsubscribe()\n }\n}\n\nfunction parseShapeData<T extends Row<unknown>>(\n shape: Shape<T>\n): UseShapeResult<T> {\n return {\n data: shape.currentRows,\n isLoading: shape.isLoading(),\n lastSyncedAt: shape.lastSyncedAt(),\n isError: shape.error !== false,\n shape,\n stream: shape.stream as ShapeStream<T>,\n error: shape.error,\n }\n}\n\nfunction shapeResultChanged<T extends Row<unknown>>(\n oldRes: UseShapeResult<T> | undefined,\n newRes: UseShapeResult<T>\n): boolean {\n return (\n !oldRes ||\n oldRes.isLoading !== newRes.isLoading ||\n oldRes.lastSyncedAt !== newRes.lastSyncedAt ||\n oldRes.isError !== newRes.isError ||\n oldRes.error !== newRes.error ||\n oldRes.shape.lastOffset !== newRes.shape.lastOffset ||\n oldRes.shape.handle !== newRes.shape.handle\n )\n}\n\nfunction identity<T>(arg: T): T {\n return arg\n}\n\ninterface UseShapeOptions<SourceData extends Row<unknown>, Selection>\n extends ShapeStreamOptions<GetExtensions<SourceData>> {\n selector?: (value: UseShapeResult<SourceData>) => Selection\n}\n\nexport function useShape<\n SourceData extends Row<unknown> = Row,\n Selection = UseShapeResult<SourceData>,\n>({\n selector = identity as (arg: UseShapeResult<SourceData>) => Selection,\n ...options\n}: UseShapeOptions<SourceData, Selection>): Selection {\n const shapeStream = getShapeStream<SourceData>(\n options as ShapeStreamOptions<GetExtensions<SourceData>>\n )\n const shape = getShape<SourceData>(shapeStream)\n\n const useShapeData = React.useMemo(() => {\n let latestShapeData: UseShapeResult<SourceData> | undefined\n\n const getSnapshot = () => {\n latestShapeData ??= parseShapeData(shape)\n return latestShapeData\n }\n\n const subscribe = (onStoreChange: () => void) => {\n // check if shape has changed between the initial snapshot\n // and subscribing, as there are no guarantees that the\n // two will occur synchronously with each other\n const newShapeData = parseShapeData(shape)\n if (shapeResultChanged(latestShapeData, newShapeData)) {\n latestShapeData = newShapeData\n onStoreChange()\n }\n\n return shapeSubscribe(shape, () => {\n latestShapeData = parseShapeData(shape)\n onStoreChange()\n })\n }\n\n return () => {\n return useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getSnapshot,\n selector\n )\n }\n }, [shape, selector])\n\n return useShapeData()\n}\n"],"mappings":"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","names":["React"]}
1
+ {"version":3,"sources":["../../src/index.ts","../../src/react-hooks.tsx"],"sourcesContent":["export * from './react-hooks'\n","import {\n Shape,\n ShapeStream,\n ShapeStreamOptions,\n Row,\n GetExtensions,\n} from '@electric-sql/client'\nimport React from 'react'\nimport { useSyncExternalStoreWithSelector } from 'use-sync-external-store/with-selector.js'\n\ntype UnknownShape = Shape<Row<unknown>>\ntype UnknownShapeStream = ShapeStream<Row<unknown>>\n\nconst streamCache = new Map<string, UnknownShapeStream>()\nconst shapeCache = new Map<UnknownShapeStream, UnknownShape>()\n\nexport async function preloadShape<T extends Row<unknown> = Row>(\n options: ShapeStreamOptions<GetExtensions<T>>\n): Promise<Shape<T>> {\n const shapeStream = getShapeStream<T>(options)\n const shape = getShape<T>(shapeStream)\n await shape.rows\n return shape\n}\n\nfunction sortObjectKeys(obj: any): any {\n if (typeof obj === `function`) return Function.prototype.toString.call(obj)\n if (typeof obj !== `object` || obj === null) return obj\n\n if (Array.isArray(obj)) {\n return obj.map(sortObjectKeys)\n }\n\n return Object.keys(obj)\n .sort()\n\n .reduce<Record<string, any>>((sorted, key) => {\n sorted[key] = sortObjectKeys(obj[key])\n return sorted\n }, {})\n}\n\nexport function sortedOptionsHash<T>(options: ShapeStreamOptions<T>): string {\n return JSON.stringify(sortObjectKeys(options))\n}\n\nexport function getShapeStream<T extends Row<unknown>>(\n options: ShapeStreamOptions<GetExtensions<T>>\n): ShapeStream<T> {\n const shapeHash = sortedOptionsHash(options)\n\n // If the stream is already cached, return it if valid\n if (streamCache.has(shapeHash)) {\n const stream = streamCache.get(shapeHash)! as ShapeStream<T>\n if (!stream.options.signal?.aborted) {\n return stream\n }\n\n // if stream is aborted, remove it and related shapes\n streamCache.delete(shapeHash)\n shapeCache.delete(stream)\n }\n\n const newShapeStream = new ShapeStream<T>(options)\n streamCache.set(shapeHash, newShapeStream)\n\n // Return the created shape\n return newShapeStream\n}\n\nexport function getShape<T extends Row<unknown>>(\n shapeStream: ShapeStream<T>\n): Shape<T> {\n // If the stream is already cached, return it if valid\n if (shapeCache.has(shapeStream)) {\n if (!shapeStream.options.signal?.aborted) {\n return shapeCache.get(shapeStream)! as Shape<T>\n }\n\n // if stream is aborted, remove it and related shapes\n streamCache.delete(sortedOptionsHash(shapeStream.options))\n shapeCache.delete(shapeStream)\n }\n\n const newShape = new Shape<T>(shapeStream)\n shapeCache.set(shapeStream, newShape)\n\n // Return the created shape\n return newShape\n}\n\nexport interface UseShapeResult<T extends Row<unknown> = Row> {\n /**\n * The array of rows that make up the Shape.\n * @type {T[]}\n */\n data: T[]\n /**\n * The Shape instance used by this useShape\n * @type {Shape<T>}\n */\n shape: Shape<T>\n /**\n * The ShapeStream instance used by this Shape\n * @type {ShapeStream<T>}\n */\n stream: ShapeStream<T>\n /** True during initial fetch. False afterwise. */\n isLoading: boolean\n /** Unix time at which we last synced. Undefined when `isLoading` is true. */\n lastSyncedAt?: number\n error: Shape<T>[`error`]\n isError: boolean\n}\n\nfunction shapeSubscribe<T extends Row<unknown>>(\n shape: Shape<T>,\n callback: () => void\n) {\n const unsubscribe = shape.subscribe(callback)\n return () => {\n unsubscribe()\n }\n}\n\nfunction parseShapeData<T extends Row<unknown>>(\n shape: Shape<T>\n): UseShapeResult<T> {\n return {\n data: shape.currentRows,\n isLoading: shape.isLoading(),\n lastSyncedAt: shape.lastSyncedAt(),\n isError: shape.error !== false,\n shape,\n stream: shape.stream as ShapeStream<T>,\n error: shape.error,\n }\n}\n\nfunction shapeResultChanged<T extends Row<unknown>>(\n oldRes: UseShapeResult<T> | undefined,\n newRes: UseShapeResult<T>\n): boolean {\n return (\n !oldRes ||\n oldRes.isLoading !== newRes.isLoading ||\n oldRes.lastSyncedAt !== newRes.lastSyncedAt ||\n oldRes.isError !== newRes.isError ||\n oldRes.error !== newRes.error ||\n oldRes.shape.lastOffset !== newRes.shape.lastOffset ||\n oldRes.shape.handle !== newRes.shape.handle\n )\n}\n\nfunction identity<T>(arg: T): T {\n return arg\n}\n\ninterface UseShapeOptions<SourceData extends Row<unknown>, Selection>\n extends ShapeStreamOptions<GetExtensions<SourceData>> {\n selector?: (value: UseShapeResult<SourceData>) => Selection\n}\n\nexport function useShape<\n SourceData extends Row<unknown> = Row,\n Selection = UseShapeResult<SourceData>,\n>({\n selector = identity as (arg: UseShapeResult<SourceData>) => Selection,\n ...options\n}: UseShapeOptions<SourceData, Selection>): Selection {\n const shapeStream = getShapeStream<SourceData>(\n options as ShapeStreamOptions<GetExtensions<SourceData>>\n )\n const shape = getShape<SourceData>(shapeStream)\n\n const useShapeData = React.useMemo(() => {\n let latestShapeData: UseShapeResult<SourceData> | undefined\n\n const getSnapshot = () => {\n latestShapeData ??= parseShapeData(shape)\n return latestShapeData\n }\n\n const subscribe = (onStoreChange: () => void) => {\n // check if shape has changed between the initial snapshot\n // and subscribing, as there are no guarantees that the\n // two will occur synchronously with each other\n const newShapeData = parseShapeData(shape)\n if (shapeResultChanged(latestShapeData, newShapeData)) {\n latestShapeData = newShapeData\n onStoreChange()\n }\n\n return shapeSubscribe(shape, () => {\n latestShapeData = parseShapeData(shape)\n onStoreChange()\n })\n }\n\n return () => {\n return useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getSnapshot,\n selector\n )\n }\n }, [shape, selector])\n\n return useShapeData()\n}\n"],"mappings":"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","names":["React"]}
@@ -1,2 +1,2 @@
1
- var f=Object.getOwnPropertySymbols;var k=Object.prototype.hasOwnProperty,R=Object.prototype.propertyIsEnumerable;var T=(e,t)=>{var n={};for(var a in e)k.call(e,a)&&t.indexOf(a)<0&&(n[a]=e[a]);if(e!=null&&f)for(var a of f(e))t.indexOf(a)<0&&R.call(e,a)&&(n[a]=e[a]);return n};var m=(e,t,n)=>new Promise((a,s)=>{var S=o=>{try{r(n.next(o))}catch(i){s(i)}},l=o=>{try{r(n.throw(o))}catch(i){s(i)}},r=o=>o.done?a(o.value):Promise.resolve(o.value).then(S,l);r((n=n.apply(e,t)).next())});import{Shape as U,ShapeStream as D}from"@electric-sql/client";import O from"react";import{useSyncExternalStoreWithSelector as E}from"use-sync-external-store/with-selector.js";var p=new Map,u=new Map;function K(e){return m(this,null,function*(){let t=y(e),n=g(t);return yield n.rows,n})}function h(e){return typeof e=="function"?Function.prototype.toString.call(e):typeof e!="object"||e===null?e:Array.isArray(e)?e.map(h):Object.keys(e).sort().reduce((t,n)=>(t[n]=h(e[n]),t),{})}function x(e){return JSON.stringify(h(e))}function y(e){var a;let t=x(e);if(p.has(t)){let s=p.get(t);if(!((a=s.options.signal)!=null&&a.aborted))return s;p.delete(t),u.delete(s)}let n=new D(e);return p.set(t,n),n}function g(e){var n;if(u.has(e)){if(!((n=e.options.signal)!=null&&n.aborted))return u.get(e);p.delete(x(e.options)),u.delete(e)}let t=new U(e);return u.set(e,t),t}function b(e,t){let n=e.subscribe(t);return()=>{n()}}function c(e){return{data:e.currentRows,isLoading:e.isLoading(),lastSyncedAt:e.lastSyncedAt(),isError:e.error!==!1,shape:e,stream:e.stream,error:e.error}}function A(e,t){return!e||e.isLoading!==t.isLoading||e.lastSyncedAt!==t.lastSyncedAt||e.isError!==t.isError||e.error!==t.error||e.shape.lastOffset!==t.shape.lastOffset||e.shape.handle!==t.shape.handle}function G(e){return e}function N(n){var a=n,{selector:e=G}=a,t=T(a,["selector"]);let s=y(t),S=g(s);return O.useMemo(()=>{let r,o=()=>(r!=null||(r=c(S)),r),i=w=>{let d=c(S);return A(r,d)&&(r=d,w()),b(S,()=>{r=c(S),w()})};return()=>E(i,o,o,e)},[S,e])()}export{g as getShape,y as getShapeStream,K as preloadShape,x as sortedOptionsHash,N as useShape};
1
+ var w=Object.getOwnPropertySymbols;var y=Object.prototype.hasOwnProperty,g=Object.prototype.propertyIsEnumerable;var d=(e,t)=>{var n={};for(var a in e)y.call(e,a)&&t.indexOf(a)<0&&(n[a]=e[a]);if(e!=null&&w)for(var a of w(e))t.indexOf(a)<0&&g.call(e,a)&&(n[a]=e[a]);return n};import{Shape as k,ShapeStream as R}from"@electric-sql/client";import U from"react";import{useSyncExternalStoreWithSelector as D}from"use-sync-external-store/with-selector.js";var S=new Map,i=new Map;async function J(e){let t=T(e),n=m(t);return await n.rows,n}function u(e){return typeof e=="function"?Function.prototype.toString.call(e):typeof e!="object"||e===null?e:Array.isArray(e)?e.map(u):Object.keys(e).sort().reduce((t,n)=>(t[n]=u(e[n]),t),{})}function f(e){return JSON.stringify(u(e))}function T(e){var a;let t=f(e);if(S.has(t)){let o=S.get(t);if(!((a=o.options.signal)!=null&&a.aborted))return o;S.delete(t),i.delete(o)}let n=new R(e);return S.set(t,n),n}function m(e){var n;if(i.has(e)){if(!((n=e.options.signal)!=null&&n.aborted))return i.get(e);S.delete(f(e.options)),i.delete(e)}let t=new k(e);return i.set(e,t),t}function O(e,t){let n=e.subscribe(t);return()=>{n()}}function p(e){return{data:e.currentRows,isLoading:e.isLoading(),lastSyncedAt:e.lastSyncedAt(),isError:e.error!==!1,shape:e,stream:e.stream,error:e.error}}function E(e,t){return!e||e.isLoading!==t.isLoading||e.lastSyncedAt!==t.lastSyncedAt||e.isError!==t.isError||e.error!==t.error||e.shape.lastOffset!==t.shape.lastOffset||e.shape.handle!==t.shape.handle}function b(e){return e}function K(n){var a=n,{selector:e=b}=a,t=d(a,["selector"]);let o=T(t),s=m(o);return U.useMemo(()=>{let r,c=()=>(r!=null||(r=p(s)),r),x=h=>{let l=p(s);return E(r,l)&&(r=l,h()),O(s,()=>{r=p(s),h()})};return()=>D(x,c,c,e)},[s,e])()}export{m as getShape,T as getShapeStream,J as preloadShape,f as sortedOptionsHash,K as useShape};
2
2
  //# sourceMappingURL=index.browser.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/react-hooks.tsx"],"sourcesContent":["import {\n Shape,\n ShapeStream,\n ShapeStreamOptions,\n Row,\n GetExtensions,\n} from '@electric-sql/client'\nimport React from 'react'\nimport { useSyncExternalStoreWithSelector } from 'use-sync-external-store/with-selector.js'\n\ntype UnknownShape = Shape<Row<unknown>>\ntype UnknownShapeStream = ShapeStream<Row<unknown>>\n\nconst streamCache = new Map<string, UnknownShapeStream>()\nconst shapeCache = new Map<UnknownShapeStream, UnknownShape>()\n\nexport async function preloadShape<T extends Row<unknown> = Row>(\n options: ShapeStreamOptions<GetExtensions<T>>\n): Promise<Shape<T>> {\n const shapeStream = getShapeStream<T>(options)\n const shape = getShape<T>(shapeStream)\n await shape.rows\n return shape\n}\n\nfunction sortObjectKeys(obj: any): any {\n if (typeof obj === `function`) return Function.prototype.toString.call(obj)\n if (typeof obj !== `object` || obj === null) return obj\n\n if (Array.isArray(obj)) {\n return obj.map(sortObjectKeys)\n }\n\n return Object.keys(obj)\n .sort()\n\n .reduce<Record<string, any>>((sorted, key) => {\n sorted[key] = sortObjectKeys(obj[key])\n return sorted\n }, {})\n}\n\nexport function sortedOptionsHash<T>(options: ShapeStreamOptions<T>): string {\n return JSON.stringify(sortObjectKeys(options))\n}\n\nexport function getShapeStream<T extends Row<unknown>>(\n options: ShapeStreamOptions<GetExtensions<T>>\n): ShapeStream<T> {\n const shapeHash = sortedOptionsHash(options)\n\n // If the stream is already cached, return it if valid\n if (streamCache.has(shapeHash)) {\n const stream = streamCache.get(shapeHash)! as ShapeStream<T>\n if (!stream.options.signal?.aborted) {\n return stream\n }\n\n // if stream is aborted, remove it and related shapes\n streamCache.delete(shapeHash)\n shapeCache.delete(stream)\n }\n\n const newShapeStream = new ShapeStream<T>(options)\n streamCache.set(shapeHash, newShapeStream)\n\n // Return the created shape\n return newShapeStream\n}\n\nexport function getShape<T extends Row<unknown>>(\n shapeStream: ShapeStream<T>\n): Shape<T> {\n // If the stream is already cached, return it if valid\n if (shapeCache.has(shapeStream)) {\n if (!shapeStream.options.signal?.aborted) {\n return shapeCache.get(shapeStream)! as Shape<T>\n }\n\n // if stream is aborted, remove it and related shapes\n streamCache.delete(sortedOptionsHash(shapeStream.options))\n shapeCache.delete(shapeStream)\n }\n\n const newShape = new Shape<T>(shapeStream)\n shapeCache.set(shapeStream, newShape)\n\n // Return the created shape\n return newShape\n}\n\nexport interface UseShapeResult<T extends Row<unknown> = Row> {\n /**\n * The array of rows that make up the Shape.\n * @type {T[]}\n */\n data: T[]\n /**\n * The Shape instance used by this useShape\n * @type {Shape<T>}\n */\n shape: Shape<T>\n /**\n * The ShapeStream instance used by this Shape\n * @type {ShapeStream<T>}\n */\n stream: ShapeStream<T>\n /** True during initial fetch. False afterwise. */\n isLoading: boolean\n /** Unix time at which we last synced. Undefined when `isLoading` is true. */\n lastSyncedAt?: number\n error: Shape<T>[`error`]\n isError: boolean\n}\n\nfunction shapeSubscribe<T extends Row<unknown>>(\n shape: Shape<T>,\n callback: () => void\n) {\n const unsubscribe = shape.subscribe(callback)\n return () => {\n unsubscribe()\n }\n}\n\nfunction parseShapeData<T extends Row<unknown>>(\n shape: Shape<T>\n): UseShapeResult<T> {\n return {\n data: shape.currentRows,\n isLoading: shape.isLoading(),\n lastSyncedAt: shape.lastSyncedAt(),\n isError: shape.error !== false,\n shape,\n stream: shape.stream as ShapeStream<T>,\n error: shape.error,\n }\n}\n\nfunction shapeResultChanged<T extends Row<unknown>>(\n oldRes: UseShapeResult<T> | undefined,\n newRes: UseShapeResult<T>\n): boolean {\n return (\n !oldRes ||\n oldRes.isLoading !== newRes.isLoading ||\n oldRes.lastSyncedAt !== newRes.lastSyncedAt ||\n oldRes.isError !== newRes.isError ||\n oldRes.error !== newRes.error ||\n oldRes.shape.lastOffset !== newRes.shape.lastOffset ||\n oldRes.shape.handle !== newRes.shape.handle\n )\n}\n\nfunction identity<T>(arg: T): T {\n return arg\n}\n\ninterface UseShapeOptions<SourceData extends Row<unknown>, Selection>\n extends ShapeStreamOptions<GetExtensions<SourceData>> {\n selector?: (value: UseShapeResult<SourceData>) => Selection\n}\n\nexport function useShape<\n SourceData extends Row<unknown> = Row,\n Selection = UseShapeResult<SourceData>,\n>({\n selector = identity as (arg: UseShapeResult<SourceData>) => Selection,\n ...options\n}: UseShapeOptions<SourceData, Selection>): Selection {\n const shapeStream = getShapeStream<SourceData>(\n options as ShapeStreamOptions<GetExtensions<SourceData>>\n )\n const shape = getShape<SourceData>(shapeStream)\n\n const useShapeData = React.useMemo(() => {\n let latestShapeData: UseShapeResult<SourceData> | undefined\n\n const getSnapshot = () => {\n latestShapeData ??= parseShapeData(shape)\n return latestShapeData\n }\n\n const subscribe = (onStoreChange: () => void) => {\n // check if shape has changed between the initial snapshot\n // and subscribing, as there are no guarantees that the\n // two will occur synchronously with each other\n const newShapeData = parseShapeData(shape)\n if (shapeResultChanged(latestShapeData, newShapeData)) {\n latestShapeData = newShapeData\n onStoreChange()\n }\n\n return shapeSubscribe(shape, () => {\n latestShapeData = parseShapeData(shape)\n onStoreChange()\n })\n }\n\n return () => {\n return useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getSnapshot,\n selector\n )\n }\n }, [shape, selector])\n\n return useShapeData()\n}\n"],"mappings":"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","names":["Shape","ShapeStream","React","useSyncExternalStoreWithSelector","streamCache","shapeCache","preloadShape","options","__async","shapeStream","getShapeStream","shape","getShape","sortObjectKeys","obj","sorted","key","sortedOptionsHash","_a","shapeHash","stream","newShapeStream","ShapeStream","newShape","Shape","shapeSubscribe","callback","unsubscribe","parseShapeData","shapeResultChanged","oldRes","newRes","identity","arg","useShape","_b","selector","__objRest","React","latestShapeData","getSnapshot","subscribe","onStoreChange","newShapeData","useSyncExternalStoreWithSelector"]}
1
+ {"version":3,"sources":["../src/react-hooks.tsx"],"sourcesContent":["import {\n Shape,\n ShapeStream,\n ShapeStreamOptions,\n Row,\n GetExtensions,\n} from '@electric-sql/client'\nimport React from 'react'\nimport { useSyncExternalStoreWithSelector } from 'use-sync-external-store/with-selector.js'\n\ntype UnknownShape = Shape<Row<unknown>>\ntype UnknownShapeStream = ShapeStream<Row<unknown>>\n\nconst streamCache = new Map<string, UnknownShapeStream>()\nconst shapeCache = new Map<UnknownShapeStream, UnknownShape>()\n\nexport async function preloadShape<T extends Row<unknown> = Row>(\n options: ShapeStreamOptions<GetExtensions<T>>\n): Promise<Shape<T>> {\n const shapeStream = getShapeStream<T>(options)\n const shape = getShape<T>(shapeStream)\n await shape.rows\n return shape\n}\n\nfunction sortObjectKeys(obj: any): any {\n if (typeof obj === `function`) return Function.prototype.toString.call(obj)\n if (typeof obj !== `object` || obj === null) return obj\n\n if (Array.isArray(obj)) {\n return obj.map(sortObjectKeys)\n }\n\n return Object.keys(obj)\n .sort()\n\n .reduce<Record<string, any>>((sorted, key) => {\n sorted[key] = sortObjectKeys(obj[key])\n return sorted\n }, {})\n}\n\nexport function sortedOptionsHash<T>(options: ShapeStreamOptions<T>): string {\n return JSON.stringify(sortObjectKeys(options))\n}\n\nexport function getShapeStream<T extends Row<unknown>>(\n options: ShapeStreamOptions<GetExtensions<T>>\n): ShapeStream<T> {\n const shapeHash = sortedOptionsHash(options)\n\n // If the stream is already cached, return it if valid\n if (streamCache.has(shapeHash)) {\n const stream = streamCache.get(shapeHash)! as ShapeStream<T>\n if (!stream.options.signal?.aborted) {\n return stream\n }\n\n // if stream is aborted, remove it and related shapes\n streamCache.delete(shapeHash)\n shapeCache.delete(stream)\n }\n\n const newShapeStream = new ShapeStream<T>(options)\n streamCache.set(shapeHash, newShapeStream)\n\n // Return the created shape\n return newShapeStream\n}\n\nexport function getShape<T extends Row<unknown>>(\n shapeStream: ShapeStream<T>\n): Shape<T> {\n // If the stream is already cached, return it if valid\n if (shapeCache.has(shapeStream)) {\n if (!shapeStream.options.signal?.aborted) {\n return shapeCache.get(shapeStream)! as Shape<T>\n }\n\n // if stream is aborted, remove it and related shapes\n streamCache.delete(sortedOptionsHash(shapeStream.options))\n shapeCache.delete(shapeStream)\n }\n\n const newShape = new Shape<T>(shapeStream)\n shapeCache.set(shapeStream, newShape)\n\n // Return the created shape\n return newShape\n}\n\nexport interface UseShapeResult<T extends Row<unknown> = Row> {\n /**\n * The array of rows that make up the Shape.\n * @type {T[]}\n */\n data: T[]\n /**\n * The Shape instance used by this useShape\n * @type {Shape<T>}\n */\n shape: Shape<T>\n /**\n * The ShapeStream instance used by this Shape\n * @type {ShapeStream<T>}\n */\n stream: ShapeStream<T>\n /** True during initial fetch. False afterwise. */\n isLoading: boolean\n /** Unix time at which we last synced. Undefined when `isLoading` is true. */\n lastSyncedAt?: number\n error: Shape<T>[`error`]\n isError: boolean\n}\n\nfunction shapeSubscribe<T extends Row<unknown>>(\n shape: Shape<T>,\n callback: () => void\n) {\n const unsubscribe = shape.subscribe(callback)\n return () => {\n unsubscribe()\n }\n}\n\nfunction parseShapeData<T extends Row<unknown>>(\n shape: Shape<T>\n): UseShapeResult<T> {\n return {\n data: shape.currentRows,\n isLoading: shape.isLoading(),\n lastSyncedAt: shape.lastSyncedAt(),\n isError: shape.error !== false,\n shape,\n stream: shape.stream as ShapeStream<T>,\n error: shape.error,\n }\n}\n\nfunction shapeResultChanged<T extends Row<unknown>>(\n oldRes: UseShapeResult<T> | undefined,\n newRes: UseShapeResult<T>\n): boolean {\n return (\n !oldRes ||\n oldRes.isLoading !== newRes.isLoading ||\n oldRes.lastSyncedAt !== newRes.lastSyncedAt ||\n oldRes.isError !== newRes.isError ||\n oldRes.error !== newRes.error ||\n oldRes.shape.lastOffset !== newRes.shape.lastOffset ||\n oldRes.shape.handle !== newRes.shape.handle\n )\n}\n\nfunction identity<T>(arg: T): T {\n return arg\n}\n\ninterface UseShapeOptions<SourceData extends Row<unknown>, Selection>\n extends ShapeStreamOptions<GetExtensions<SourceData>> {\n selector?: (value: UseShapeResult<SourceData>) => Selection\n}\n\nexport function useShape<\n SourceData extends Row<unknown> = Row,\n Selection = UseShapeResult<SourceData>,\n>({\n selector = identity as (arg: UseShapeResult<SourceData>) => Selection,\n ...options\n}: UseShapeOptions<SourceData, Selection>): Selection {\n const shapeStream = getShapeStream<SourceData>(\n options as ShapeStreamOptions<GetExtensions<SourceData>>\n )\n const shape = getShape<SourceData>(shapeStream)\n\n const useShapeData = React.useMemo(() => {\n let latestShapeData: UseShapeResult<SourceData> | undefined\n\n const getSnapshot = () => {\n latestShapeData ??= parseShapeData(shape)\n return latestShapeData\n }\n\n const subscribe = (onStoreChange: () => void) => {\n // check if shape has changed between the initial snapshot\n // and subscribing, as there are no guarantees that the\n // two will occur synchronously with each other\n const newShapeData = parseShapeData(shape)\n if (shapeResultChanged(latestShapeData, newShapeData)) {\n latestShapeData = newShapeData\n onStoreChange()\n }\n\n return shapeSubscribe(shape, () => {\n latestShapeData = parseShapeData(shape)\n onStoreChange()\n })\n }\n\n return () => {\n return useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getSnapshot,\n selector\n )\n }\n }, [shape, selector])\n\n return useShapeData()\n}\n"],"mappings":"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","names":["Shape","ShapeStream","React","useSyncExternalStoreWithSelector","streamCache","shapeCache","preloadShape","options","shapeStream","getShapeStream","shape","getShape","sortObjectKeys","obj","sorted","key","sortedOptionsHash","_a","shapeHash","stream","newShapeStream","ShapeStream","newShape","Shape","shapeSubscribe","callback","unsubscribe","parseShapeData","shapeResultChanged","oldRes","newRes","identity","arg","useShape","_b","selector","__objRest","React","latestShapeData","getSnapshot","subscribe","onStoreChange","newShapeData","useSyncExternalStoreWithSelector"]}
package/dist/index.mjs CHANGED
@@ -13,26 +13,6 @@ var __objRest = (source, exclude) => {
13
13
  }
14
14
  return target;
15
15
  };
16
- var __async = (__this, __arguments, generator) => {
17
- return new Promise((resolve, reject) => {
18
- var fulfilled = (value) => {
19
- try {
20
- step(generator.next(value));
21
- } catch (e) {
22
- reject(e);
23
- }
24
- };
25
- var rejected = (value) => {
26
- try {
27
- step(generator.throw(value));
28
- } catch (e) {
29
- reject(e);
30
- }
31
- };
32
- var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
33
- step((generator = generator.apply(__this, __arguments)).next());
34
- });
35
- };
36
16
 
37
17
  // src/react-hooks.tsx
38
18
  import {
@@ -43,13 +23,11 @@ import React from "react";
43
23
  import { useSyncExternalStoreWithSelector } from "use-sync-external-store/with-selector.js";
44
24
  var streamCache = /* @__PURE__ */ new Map();
45
25
  var shapeCache = /* @__PURE__ */ new Map();
46
- function preloadShape(options) {
47
- return __async(this, null, function* () {
48
- const shapeStream = getShapeStream(options);
49
- const shape = getShape(shapeStream);
50
- yield shape.rows;
51
- return shape;
52
- });
26
+ async function preloadShape(options) {
27
+ const shapeStream = getShapeStream(options);
28
+ const shape = getShape(shapeStream);
29
+ await shape.rows;
30
+ return shape;
53
31
  }
54
32
  function sortObjectKeys(obj) {
55
33
  if (typeof obj === `function`) return Function.prototype.toString.call(obj);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/react-hooks.tsx"],"sourcesContent":["import {\n Shape,\n ShapeStream,\n ShapeStreamOptions,\n Row,\n GetExtensions,\n} from '@electric-sql/client'\nimport React from 'react'\nimport { useSyncExternalStoreWithSelector } from 'use-sync-external-store/with-selector.js'\n\ntype UnknownShape = Shape<Row<unknown>>\ntype UnknownShapeStream = ShapeStream<Row<unknown>>\n\nconst streamCache = new Map<string, UnknownShapeStream>()\nconst shapeCache = new Map<UnknownShapeStream, UnknownShape>()\n\nexport async function preloadShape<T extends Row<unknown> = Row>(\n options: ShapeStreamOptions<GetExtensions<T>>\n): Promise<Shape<T>> {\n const shapeStream = getShapeStream<T>(options)\n const shape = getShape<T>(shapeStream)\n await shape.rows\n return shape\n}\n\nfunction sortObjectKeys(obj: any): any {\n if (typeof obj === `function`) return Function.prototype.toString.call(obj)\n if (typeof obj !== `object` || obj === null) return obj\n\n if (Array.isArray(obj)) {\n return obj.map(sortObjectKeys)\n }\n\n return Object.keys(obj)\n .sort()\n\n .reduce<Record<string, any>>((sorted, key) => {\n sorted[key] = sortObjectKeys(obj[key])\n return sorted\n }, {})\n}\n\nexport function sortedOptionsHash<T>(options: ShapeStreamOptions<T>): string {\n return JSON.stringify(sortObjectKeys(options))\n}\n\nexport function getShapeStream<T extends Row<unknown>>(\n options: ShapeStreamOptions<GetExtensions<T>>\n): ShapeStream<T> {\n const shapeHash = sortedOptionsHash(options)\n\n // If the stream is already cached, return it if valid\n if (streamCache.has(shapeHash)) {\n const stream = streamCache.get(shapeHash)! as ShapeStream<T>\n if (!stream.options.signal?.aborted) {\n return stream\n }\n\n // if stream is aborted, remove it and related shapes\n streamCache.delete(shapeHash)\n shapeCache.delete(stream)\n }\n\n const newShapeStream = new ShapeStream<T>(options)\n streamCache.set(shapeHash, newShapeStream)\n\n // Return the created shape\n return newShapeStream\n}\n\nexport function getShape<T extends Row<unknown>>(\n shapeStream: ShapeStream<T>\n): Shape<T> {\n // If the stream is already cached, return it if valid\n if (shapeCache.has(shapeStream)) {\n if (!shapeStream.options.signal?.aborted) {\n return shapeCache.get(shapeStream)! as Shape<T>\n }\n\n // if stream is aborted, remove it and related shapes\n streamCache.delete(sortedOptionsHash(shapeStream.options))\n shapeCache.delete(shapeStream)\n }\n\n const newShape = new Shape<T>(shapeStream)\n shapeCache.set(shapeStream, newShape)\n\n // Return the created shape\n return newShape\n}\n\nexport interface UseShapeResult<T extends Row<unknown> = Row> {\n /**\n * The array of rows that make up the Shape.\n * @type {T[]}\n */\n data: T[]\n /**\n * The Shape instance used by this useShape\n * @type {Shape<T>}\n */\n shape: Shape<T>\n /**\n * The ShapeStream instance used by this Shape\n * @type {ShapeStream<T>}\n */\n stream: ShapeStream<T>\n /** True during initial fetch. False afterwise. */\n isLoading: boolean\n /** Unix time at which we last synced. Undefined when `isLoading` is true. */\n lastSyncedAt?: number\n error: Shape<T>[`error`]\n isError: boolean\n}\n\nfunction shapeSubscribe<T extends Row<unknown>>(\n shape: Shape<T>,\n callback: () => void\n) {\n const unsubscribe = shape.subscribe(callback)\n return () => {\n unsubscribe()\n }\n}\n\nfunction parseShapeData<T extends Row<unknown>>(\n shape: Shape<T>\n): UseShapeResult<T> {\n return {\n data: shape.currentRows,\n isLoading: shape.isLoading(),\n lastSyncedAt: shape.lastSyncedAt(),\n isError: shape.error !== false,\n shape,\n stream: shape.stream as ShapeStream<T>,\n error: shape.error,\n }\n}\n\nfunction shapeResultChanged<T extends Row<unknown>>(\n oldRes: UseShapeResult<T> | undefined,\n newRes: UseShapeResult<T>\n): boolean {\n return (\n !oldRes ||\n oldRes.isLoading !== newRes.isLoading ||\n oldRes.lastSyncedAt !== newRes.lastSyncedAt ||\n oldRes.isError !== newRes.isError ||\n oldRes.error !== newRes.error ||\n oldRes.shape.lastOffset !== newRes.shape.lastOffset ||\n oldRes.shape.handle !== newRes.shape.handle\n )\n}\n\nfunction identity<T>(arg: T): T {\n return arg\n}\n\ninterface UseShapeOptions<SourceData extends Row<unknown>, Selection>\n extends ShapeStreamOptions<GetExtensions<SourceData>> {\n selector?: (value: UseShapeResult<SourceData>) => Selection\n}\n\nexport function useShape<\n SourceData extends Row<unknown> = Row,\n Selection = UseShapeResult<SourceData>,\n>({\n selector = identity as (arg: UseShapeResult<SourceData>) => Selection,\n ...options\n}: UseShapeOptions<SourceData, Selection>): Selection {\n const shapeStream = getShapeStream<SourceData>(\n options as ShapeStreamOptions<GetExtensions<SourceData>>\n )\n const shape = getShape<SourceData>(shapeStream)\n\n const useShapeData = React.useMemo(() => {\n let latestShapeData: UseShapeResult<SourceData> | undefined\n\n const getSnapshot = () => {\n latestShapeData ??= parseShapeData(shape)\n return latestShapeData\n }\n\n const subscribe = (onStoreChange: () => void) => {\n // check if shape has changed between the initial snapshot\n // and subscribing, as there are no guarantees that the\n // two will occur synchronously with each other\n const newShapeData = parseShapeData(shape)\n if (shapeResultChanged(latestShapeData, newShapeData)) {\n latestShapeData = newShapeData\n onStoreChange()\n }\n\n return shapeSubscribe(shape, () => {\n latestShapeData = parseShapeData(shape)\n onStoreChange()\n })\n }\n\n return () => {\n return useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getSnapshot,\n selector\n )\n }\n }, [shape, selector])\n\n return useShapeData()\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA,EACE;AAAA,EACA;AAAA,OAIK;AACP,OAAO,WAAW;AAClB,SAAS,wCAAwC;AAKjD,IAAM,cAAc,oBAAI,IAAgC;AACxD,IAAM,aAAa,oBAAI,IAAsC;AAE7D,SAAsB,aACpB,SACmB;AAAA;AACnB,UAAM,cAAc,eAAkB,OAAO;AAC7C,UAAM,QAAQ,SAAY,WAAW;AACrC,UAAM,MAAM;AACZ,WAAO;AAAA,EACT;AAAA;AAEA,SAAS,eAAe,KAAe;AACrC,MAAI,OAAO,QAAQ,WAAY,QAAO,SAAS,UAAU,SAAS,KAAK,GAAG;AAC1E,MAAI,OAAO,QAAQ,YAAY,QAAQ,KAAM,QAAO;AAEpD,MAAI,MAAM,QAAQ,GAAG,GAAG;AACtB,WAAO,IAAI,IAAI,cAAc;AAAA,EAC/B;AAEA,SAAO,OAAO,KAAK,GAAG,EACnB,KAAK,EAEL,OAA4B,CAAC,QAAQ,QAAQ;AAC5C,WAAO,GAAG,IAAI,eAAe,IAAI,GAAG,CAAC;AACrC,WAAO;AAAA,EACT,GAAG,CAAC,CAAC;AACT;AAEO,SAAS,kBAAqB,SAAwC;AAC3E,SAAO,KAAK,UAAU,eAAe,OAAO,CAAC;AAC/C;AAEO,SAAS,eACd,SACgB;AAhDlB;AAiDE,QAAM,YAAY,kBAAkB,OAAO;AAG3C,MAAI,YAAY,IAAI,SAAS,GAAG;AAC9B,UAAM,SAAS,YAAY,IAAI,SAAS;AACxC,QAAI,GAAC,YAAO,QAAQ,WAAf,mBAAuB,UAAS;AACnC,aAAO;AAAA,IACT;AAGA,gBAAY,OAAO,SAAS;AAC5B,eAAW,OAAO,MAAM;AAAA,EAC1B;AAEA,QAAM,iBAAiB,IAAI,YAAe,OAAO;AACjD,cAAY,IAAI,WAAW,cAAc;AAGzC,SAAO;AACT;AAEO,SAAS,SACd,aACU;AAxEZ;AA0EE,MAAI,WAAW,IAAI,WAAW,GAAG;AAC/B,QAAI,GAAC,iBAAY,QAAQ,WAApB,mBAA4B,UAAS;AACxC,aAAO,WAAW,IAAI,WAAW;AAAA,IACnC;AAGA,gBAAY,OAAO,kBAAkB,YAAY,OAAO,CAAC;AACzD,eAAW,OAAO,WAAW;AAAA,EAC/B;AAEA,QAAM,WAAW,IAAI,MAAS,WAAW;AACzC,aAAW,IAAI,aAAa,QAAQ;AAGpC,SAAO;AACT;AA0BA,SAAS,eACP,OACA,UACA;AACA,QAAM,cAAc,MAAM,UAAU,QAAQ;AAC5C,SAAO,MAAM;AACX,gBAAY;AAAA,EACd;AACF;AAEA,SAAS,eACP,OACmB;AACnB,SAAO;AAAA,IACL,MAAM,MAAM;AAAA,IACZ,WAAW,MAAM,UAAU;AAAA,IAC3B,cAAc,MAAM,aAAa;AAAA,IACjC,SAAS,MAAM,UAAU;AAAA,IACzB;AAAA,IACA,QAAQ,MAAM;AAAA,IACd,OAAO,MAAM;AAAA,EACf;AACF;AAEA,SAAS,mBACP,QACA,QACS;AACT,SACE,CAAC,UACD,OAAO,cAAc,OAAO,aAC5B,OAAO,iBAAiB,OAAO,gBAC/B,OAAO,YAAY,OAAO,WAC1B,OAAO,UAAU,OAAO,SACxB,OAAO,MAAM,eAAe,OAAO,MAAM,cACzC,OAAO,MAAM,WAAW,OAAO,MAAM;AAEzC;AAEA,SAAS,SAAY,KAAW;AAC9B,SAAO;AACT;AAOO,SAAS,SAGd,IAGoD;AAHpD,eACA;AAAA,eAAW;AAAA,EAvKb,IAsKE,IAEG,oBAFH,IAEG;AAAA,IADH;AAAA;AAGA,QAAM,cAAc;AAAA,IAClB;AAAA,EACF;AACA,QAAM,QAAQ,SAAqB,WAAW;AAE9C,QAAM,eAAe,MAAM,QAAQ,MAAM;AACvC,QAAI;AAEJ,UAAM,cAAc,MAAM;AACxB,oEAAoB,eAAe,KAAK;AACxC,aAAO;AAAA,IACT;AAEA,UAAM,YAAY,CAAC,kBAA8B;AAI/C,YAAM,eAAe,eAAe,KAAK;AACzC,UAAI,mBAAmB,iBAAiB,YAAY,GAAG;AACrD,0BAAkB;AAClB,sBAAc;AAAA,MAChB;AAEA,aAAO,eAAe,OAAO,MAAM;AACjC,0BAAkB,eAAe,KAAK;AACtC,sBAAc;AAAA,MAChB,CAAC;AAAA,IACH;AAEA,WAAO,MAAM;AACX,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF,GAAG,CAAC,OAAO,QAAQ,CAAC;AAEpB,SAAO,aAAa;AACtB;","names":[]}
1
+ {"version":3,"sources":["../src/react-hooks.tsx"],"sourcesContent":["import {\n Shape,\n ShapeStream,\n ShapeStreamOptions,\n Row,\n GetExtensions,\n} from '@electric-sql/client'\nimport React from 'react'\nimport { useSyncExternalStoreWithSelector } from 'use-sync-external-store/with-selector.js'\n\ntype UnknownShape = Shape<Row<unknown>>\ntype UnknownShapeStream = ShapeStream<Row<unknown>>\n\nconst streamCache = new Map<string, UnknownShapeStream>()\nconst shapeCache = new Map<UnknownShapeStream, UnknownShape>()\n\nexport async function preloadShape<T extends Row<unknown> = Row>(\n options: ShapeStreamOptions<GetExtensions<T>>\n): Promise<Shape<T>> {\n const shapeStream = getShapeStream<T>(options)\n const shape = getShape<T>(shapeStream)\n await shape.rows\n return shape\n}\n\nfunction sortObjectKeys(obj: any): any {\n if (typeof obj === `function`) return Function.prototype.toString.call(obj)\n if (typeof obj !== `object` || obj === null) return obj\n\n if (Array.isArray(obj)) {\n return obj.map(sortObjectKeys)\n }\n\n return Object.keys(obj)\n .sort()\n\n .reduce<Record<string, any>>((sorted, key) => {\n sorted[key] = sortObjectKeys(obj[key])\n return sorted\n }, {})\n}\n\nexport function sortedOptionsHash<T>(options: ShapeStreamOptions<T>): string {\n return JSON.stringify(sortObjectKeys(options))\n}\n\nexport function getShapeStream<T extends Row<unknown>>(\n options: ShapeStreamOptions<GetExtensions<T>>\n): ShapeStream<T> {\n const shapeHash = sortedOptionsHash(options)\n\n // If the stream is already cached, return it if valid\n if (streamCache.has(shapeHash)) {\n const stream = streamCache.get(shapeHash)! as ShapeStream<T>\n if (!stream.options.signal?.aborted) {\n return stream\n }\n\n // if stream is aborted, remove it and related shapes\n streamCache.delete(shapeHash)\n shapeCache.delete(stream)\n }\n\n const newShapeStream = new ShapeStream<T>(options)\n streamCache.set(shapeHash, newShapeStream)\n\n // Return the created shape\n return newShapeStream\n}\n\nexport function getShape<T extends Row<unknown>>(\n shapeStream: ShapeStream<T>\n): Shape<T> {\n // If the stream is already cached, return it if valid\n if (shapeCache.has(shapeStream)) {\n if (!shapeStream.options.signal?.aborted) {\n return shapeCache.get(shapeStream)! as Shape<T>\n }\n\n // if stream is aborted, remove it and related shapes\n streamCache.delete(sortedOptionsHash(shapeStream.options))\n shapeCache.delete(shapeStream)\n }\n\n const newShape = new Shape<T>(shapeStream)\n shapeCache.set(shapeStream, newShape)\n\n // Return the created shape\n return newShape\n}\n\nexport interface UseShapeResult<T extends Row<unknown> = Row> {\n /**\n * The array of rows that make up the Shape.\n * @type {T[]}\n */\n data: T[]\n /**\n * The Shape instance used by this useShape\n * @type {Shape<T>}\n */\n shape: Shape<T>\n /**\n * The ShapeStream instance used by this Shape\n * @type {ShapeStream<T>}\n */\n stream: ShapeStream<T>\n /** True during initial fetch. False afterwise. */\n isLoading: boolean\n /** Unix time at which we last synced. Undefined when `isLoading` is true. */\n lastSyncedAt?: number\n error: Shape<T>[`error`]\n isError: boolean\n}\n\nfunction shapeSubscribe<T extends Row<unknown>>(\n shape: Shape<T>,\n callback: () => void\n) {\n const unsubscribe = shape.subscribe(callback)\n return () => {\n unsubscribe()\n }\n}\n\nfunction parseShapeData<T extends Row<unknown>>(\n shape: Shape<T>\n): UseShapeResult<T> {\n return {\n data: shape.currentRows,\n isLoading: shape.isLoading(),\n lastSyncedAt: shape.lastSyncedAt(),\n isError: shape.error !== false,\n shape,\n stream: shape.stream as ShapeStream<T>,\n error: shape.error,\n }\n}\n\nfunction shapeResultChanged<T extends Row<unknown>>(\n oldRes: UseShapeResult<T> | undefined,\n newRes: UseShapeResult<T>\n): boolean {\n return (\n !oldRes ||\n oldRes.isLoading !== newRes.isLoading ||\n oldRes.lastSyncedAt !== newRes.lastSyncedAt ||\n oldRes.isError !== newRes.isError ||\n oldRes.error !== newRes.error ||\n oldRes.shape.lastOffset !== newRes.shape.lastOffset ||\n oldRes.shape.handle !== newRes.shape.handle\n )\n}\n\nfunction identity<T>(arg: T): T {\n return arg\n}\n\ninterface UseShapeOptions<SourceData extends Row<unknown>, Selection>\n extends ShapeStreamOptions<GetExtensions<SourceData>> {\n selector?: (value: UseShapeResult<SourceData>) => Selection\n}\n\nexport function useShape<\n SourceData extends Row<unknown> = Row,\n Selection = UseShapeResult<SourceData>,\n>({\n selector = identity as (arg: UseShapeResult<SourceData>) => Selection,\n ...options\n}: UseShapeOptions<SourceData, Selection>): Selection {\n const shapeStream = getShapeStream<SourceData>(\n options as ShapeStreamOptions<GetExtensions<SourceData>>\n )\n const shape = getShape<SourceData>(shapeStream)\n\n const useShapeData = React.useMemo(() => {\n let latestShapeData: UseShapeResult<SourceData> | undefined\n\n const getSnapshot = () => {\n latestShapeData ??= parseShapeData(shape)\n return latestShapeData\n }\n\n const subscribe = (onStoreChange: () => void) => {\n // check if shape has changed between the initial snapshot\n // and subscribing, as there are no guarantees that the\n // two will occur synchronously with each other\n const newShapeData = parseShapeData(shape)\n if (shapeResultChanged(latestShapeData, newShapeData)) {\n latestShapeData = newShapeData\n onStoreChange()\n }\n\n return shapeSubscribe(shape, () => {\n latestShapeData = parseShapeData(shape)\n onStoreChange()\n })\n }\n\n return () => {\n return useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getSnapshot,\n selector\n )\n }\n }, [shape, selector])\n\n return useShapeData()\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAAA;AAAA,EACE;AAAA,EACA;AAAA,OAIK;AACP,OAAO,WAAW;AAClB,SAAS,wCAAwC;AAKjD,IAAM,cAAc,oBAAI,IAAgC;AACxD,IAAM,aAAa,oBAAI,IAAsC;AAE7D,eAAsB,aACpB,SACmB;AACnB,QAAM,cAAc,eAAkB,OAAO;AAC7C,QAAM,QAAQ,SAAY,WAAW;AACrC,QAAM,MAAM;AACZ,SAAO;AACT;AAEA,SAAS,eAAe,KAAe;AACrC,MAAI,OAAO,QAAQ,WAAY,QAAO,SAAS,UAAU,SAAS,KAAK,GAAG;AAC1E,MAAI,OAAO,QAAQ,YAAY,QAAQ,KAAM,QAAO;AAEpD,MAAI,MAAM,QAAQ,GAAG,GAAG;AACtB,WAAO,IAAI,IAAI,cAAc;AAAA,EAC/B;AAEA,SAAO,OAAO,KAAK,GAAG,EACnB,KAAK,EAEL,OAA4B,CAAC,QAAQ,QAAQ;AAC5C,WAAO,GAAG,IAAI,eAAe,IAAI,GAAG,CAAC;AACrC,WAAO;AAAA,EACT,GAAG,CAAC,CAAC;AACT;AAEO,SAAS,kBAAqB,SAAwC;AAC3E,SAAO,KAAK,UAAU,eAAe,OAAO,CAAC;AAC/C;AAEO,SAAS,eACd,SACgB;AAhDlB;AAiDE,QAAM,YAAY,kBAAkB,OAAO;AAG3C,MAAI,YAAY,IAAI,SAAS,GAAG;AAC9B,UAAM,SAAS,YAAY,IAAI,SAAS;AACxC,QAAI,GAAC,YAAO,QAAQ,WAAf,mBAAuB,UAAS;AACnC,aAAO;AAAA,IACT;AAGA,gBAAY,OAAO,SAAS;AAC5B,eAAW,OAAO,MAAM;AAAA,EAC1B;AAEA,QAAM,iBAAiB,IAAI,YAAe,OAAO;AACjD,cAAY,IAAI,WAAW,cAAc;AAGzC,SAAO;AACT;AAEO,SAAS,SACd,aACU;AAxEZ;AA0EE,MAAI,WAAW,IAAI,WAAW,GAAG;AAC/B,QAAI,GAAC,iBAAY,QAAQ,WAApB,mBAA4B,UAAS;AACxC,aAAO,WAAW,IAAI,WAAW;AAAA,IACnC;AAGA,gBAAY,OAAO,kBAAkB,YAAY,OAAO,CAAC;AACzD,eAAW,OAAO,WAAW;AAAA,EAC/B;AAEA,QAAM,WAAW,IAAI,MAAS,WAAW;AACzC,aAAW,IAAI,aAAa,QAAQ;AAGpC,SAAO;AACT;AA0BA,SAAS,eACP,OACA,UACA;AACA,QAAM,cAAc,MAAM,UAAU,QAAQ;AAC5C,SAAO,MAAM;AACX,gBAAY;AAAA,EACd;AACF;AAEA,SAAS,eACP,OACmB;AACnB,SAAO;AAAA,IACL,MAAM,MAAM;AAAA,IACZ,WAAW,MAAM,UAAU;AAAA,IAC3B,cAAc,MAAM,aAAa;AAAA,IACjC,SAAS,MAAM,UAAU;AAAA,IACzB;AAAA,IACA,QAAQ,MAAM;AAAA,IACd,OAAO,MAAM;AAAA,EACf;AACF;AAEA,SAAS,mBACP,QACA,QACS;AACT,SACE,CAAC,UACD,OAAO,cAAc,OAAO,aAC5B,OAAO,iBAAiB,OAAO,gBAC/B,OAAO,YAAY,OAAO,WAC1B,OAAO,UAAU,OAAO,SACxB,OAAO,MAAM,eAAe,OAAO,MAAM,cACzC,OAAO,MAAM,WAAW,OAAO,MAAM;AAEzC;AAEA,SAAS,SAAY,KAAW;AAC9B,SAAO;AACT;AAOO,SAAS,SAGd,IAGoD;AAHpD,eACA;AAAA,eAAW;AAAA,EAvKb,IAsKE,IAEG,oBAFH,IAEG;AAAA,IADH;AAAA;AAGA,QAAM,cAAc;AAAA,IAClB;AAAA,EACF;AACA,QAAM,QAAQ,SAAqB,WAAW;AAE9C,QAAM,eAAe,MAAM,QAAQ,MAAM;AACvC,QAAI;AAEJ,UAAM,cAAc,MAAM;AACxB,oEAAoB,eAAe,KAAK;AACxC,aAAO;AAAA,IACT;AAEA,UAAM,YAAY,CAAC,kBAA8B;AAI/C,YAAM,eAAe,eAAe,KAAK;AACzC,UAAI,mBAAmB,iBAAiB,YAAY,GAAG;AACrD,0BAAkB;AAClB,sBAAc;AAAA,MAChB;AAEA,aAAO,eAAe,OAAO,MAAM;AACjC,0BAAkB,eAAe,KAAK;AACtC,sBAAc;AAAA,MAChB,CAAC;AAAA,IACH;AAEA,WAAO,MAAM;AACX,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF,GAAG,CAAC,OAAO,QAAQ,CAAC;AAEpB,SAAO,aAAa;AACtB;","names":[]}
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@electric-sql/react",
3
3
  "description": "React hooks for ElectricSQL",
4
- "version": "1.0.22",
4
+ "version": "1.0.24",
5
5
  "author": "ElectricSQL team and contributors.",
6
6
  "bugs": {
7
7
  "url": "https://github.com/electric-sql/electric/issues"
8
8
  },
9
9
  "dependencies": {
10
10
  "use-sync-external-store": "^1.2.2",
11
- "@electric-sql/client": "1.2.1"
11
+ "@electric-sql/client": "1.3.0"
12
12
  },
13
13
  "devDependencies": {
14
14
  "@testing-library/react": "^16.0.0",