@livestore/react 0.4.0-dev.21 → 0.4.0-dev.23
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/README.md +1 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/StoreRegistryContext.d.ts +56 -0
- package/dist/StoreRegistryContext.d.ts.map +1 -0
- package/dist/StoreRegistryContext.js +61 -0
- package/dist/StoreRegistryContext.js.map +1 -0
- package/dist/__tests__/fixture.d.ts +8 -280
- package/dist/__tests__/fixture.d.ts.map +1 -1
- package/dist/__tests__/fixture.js +9 -84
- package/dist/__tests__/fixture.js.map +1 -1
- package/dist/experimental/components/LiveList.d.ts +4 -2
- package/dist/experimental/components/LiveList.d.ts.map +1 -1
- package/dist/experimental/components/LiveList.js +9 -7
- package/dist/experimental/components/LiveList.js.map +1 -1
- package/dist/experimental/mod.d.ts +0 -1
- package/dist/experimental/mod.d.ts.map +1 -1
- package/dist/experimental/mod.js +0 -1
- package/dist/experimental/mod.js.map +1 -1
- package/dist/mod.d.ts +8 -5
- package/dist/mod.d.ts.map +1 -1
- package/dist/mod.js +6 -4
- package/dist/mod.js.map +1 -1
- package/dist/useClientDocument.d.ts +1 -26
- package/dist/useClientDocument.d.ts.map +1 -1
- package/dist/useClientDocument.js +3 -17
- package/dist/useClientDocument.js.map +1 -1
- package/dist/useClientDocument.test.js +12 -4
- package/dist/useClientDocument.test.js.map +1 -1
- package/dist/useQuery.d.ts +4 -5
- package/dist/useQuery.d.ts.map +1 -1
- package/dist/useQuery.js +12 -85
- package/dist/useQuery.js.map +1 -1
- package/dist/useQuery.test.js +7 -8
- package/dist/useQuery.test.js.map +1 -1
- package/dist/useRcResource.d.ts.map +1 -1
- package/dist/useRcResource.js +9 -5
- package/dist/useRcResource.js.map +1 -1
- package/dist/useRcResource.test.js +1 -1
- package/dist/useRcResource.test.js.map +1 -1
- package/dist/useStore.d.ts +61 -46
- package/dist/useStore.d.ts.map +1 -1
- package/dist/useStore.js +75 -60
- package/dist/useStore.js.map +1 -1
- package/dist/useStore.test.d.ts.map +1 -0
- package/dist/{experimental/multi-store/useStore.test.js → useStore.test.js} +70 -27
- package/dist/useStore.test.js.map +1 -0
- package/dist/useSyncStatus.d.ts +22 -0
- package/dist/useSyncStatus.d.ts.map +1 -0
- package/dist/useSyncStatus.js +28 -0
- package/dist/useSyncStatus.js.map +1 -0
- package/package.json +69 -26
- package/src/StoreRegistryContext.tsx +70 -0
- package/src/__snapshots__/useClientDocument.test.tsx.snap +112 -78
- package/src/__tests__/fixture.tsx +23 -118
- package/src/experimental/components/LiveList.tsx +22 -9
- package/src/experimental/mod.ts +0 -1
- package/src/mod.ts +8 -12
- package/src/useClientDocument.test.tsx +16 -6
- package/src/useClientDocument.ts +7 -61
- package/src/useQuery.test.tsx +8 -8
- package/src/useQuery.ts +30 -119
- package/src/useRcResource.test.tsx +1 -1
- package/src/useRcResource.ts +10 -5
- package/src/{experimental/multi-store/useStore.test.tsx → useStore.test.tsx} +117 -39
- package/src/useStore.ts +106 -65
- package/src/useSyncStatus.ts +34 -0
- package/dist/LiveStoreContext.d.ts +0 -40
- package/dist/LiveStoreContext.d.ts.map +0 -1
- package/dist/LiveStoreContext.js +0 -21
- package/dist/LiveStoreContext.js.map +0 -1
- package/dist/LiveStoreProvider.d.ts +0 -73
- package/dist/LiveStoreProvider.d.ts.map +0 -1
- package/dist/LiveStoreProvider.js +0 -233
- package/dist/LiveStoreProvider.js.map +0 -1
- package/dist/LiveStoreProvider.test.d.ts +0 -2
- package/dist/LiveStoreProvider.test.d.ts.map +0 -1
- package/dist/LiveStoreProvider.test.js +0 -117
- package/dist/LiveStoreProvider.test.js.map +0 -1
- package/dist/experimental/multi-store/StoreRegistry.d.ts +0 -105
- package/dist/experimental/multi-store/StoreRegistry.d.ts.map +0 -1
- package/dist/experimental/multi-store/StoreRegistry.js +0 -184
- package/dist/experimental/multi-store/StoreRegistry.js.map +0 -1
- package/dist/experimental/multi-store/StoreRegistry.test.d.ts +0 -2
- package/dist/experimental/multi-store/StoreRegistry.test.d.ts.map +0 -1
- package/dist/experimental/multi-store/StoreRegistry.test.js +0 -381
- package/dist/experimental/multi-store/StoreRegistry.test.js.map +0 -1
- package/dist/experimental/multi-store/StoreRegistryContext.d.ts +0 -10
- package/dist/experimental/multi-store/StoreRegistryContext.d.ts.map +0 -1
- package/dist/experimental/multi-store/StoreRegistryContext.js +0 -15
- package/dist/experimental/multi-store/StoreRegistryContext.js.map +0 -1
- package/dist/experimental/multi-store/mod.d.ts +0 -6
- package/dist/experimental/multi-store/mod.d.ts.map +0 -1
- package/dist/experimental/multi-store/mod.js +0 -6
- package/dist/experimental/multi-store/mod.js.map +0 -1
- package/dist/experimental/multi-store/storeOptions.d.ts +0 -4
- package/dist/experimental/multi-store/storeOptions.d.ts.map +0 -1
- package/dist/experimental/multi-store/storeOptions.js +0 -4
- package/dist/experimental/multi-store/storeOptions.js.map +0 -1
- package/dist/experimental/multi-store/types.d.ts +0 -25
- package/dist/experimental/multi-store/types.d.ts.map +0 -1
- package/dist/experimental/multi-store/types.js +0 -2
- package/dist/experimental/multi-store/types.js.map +0 -1
- package/dist/experimental/multi-store/useStore.d.ts +0 -11
- package/dist/experimental/multi-store/useStore.d.ts.map +0 -1
- package/dist/experimental/multi-store/useStore.js +0 -16
- package/dist/experimental/multi-store/useStore.js.map +0 -1
- package/dist/experimental/multi-store/useStore.test.d.ts.map +0 -1
- package/dist/experimental/multi-store/useStore.test.js.map +0 -1
- package/dist/utils/stack-info.d.ts +0 -4
- package/dist/utils/stack-info.d.ts.map +0 -1
- package/dist/utils/stack-info.js +0 -10
- package/dist/utils/stack-info.js.map +0 -1
- package/src/LiveStoreContext.ts +0 -41
- package/src/LiveStoreProvider.test.tsx +0 -248
- package/src/LiveStoreProvider.tsx +0 -430
- package/src/ambient.d.ts +0 -1
- package/src/experimental/multi-store/StoreRegistry.test.ts +0 -518
- package/src/experimental/multi-store/StoreRegistry.ts +0 -253
- package/src/experimental/multi-store/StoreRegistryContext.tsx +0 -23
- package/src/experimental/multi-store/mod.ts +0 -5
- package/src/experimental/multi-store/storeOptions.ts +0 -8
- package/src/experimental/multi-store/types.ts +0 -37
- package/src/experimental/multi-store/useStore.ts +0 -26
- package/src/utils/stack-info.ts +0 -13
- /package/dist/{experimental/multi-store/useStore.test.d.ts → useStore.test.d.ts} +0 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* React hook that subscribes to sync status changes.
|
|
4
|
+
*
|
|
5
|
+
* Returns the current synchronization status between the client session and
|
|
6
|
+
* the leader thread. The component re-renders whenever the sync status changes.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```tsx
|
|
10
|
+
* function SyncIndicator() {
|
|
11
|
+
* const status = store.useSyncStatus()
|
|
12
|
+
* return <span>{status.isSynced ? '✓ Synced' : `Syncing (${status.pendingCount} pending)...`}</span>
|
|
13
|
+
* }
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* @param options - Options containing the store instance
|
|
17
|
+
* @returns The current sync status
|
|
18
|
+
*/
|
|
19
|
+
export const useSyncStatus = (options) => {
|
|
20
|
+
const { store } = options;
|
|
21
|
+
const [status, setStatus] = React.useState(() => store.syncStatus());
|
|
22
|
+
React.useEffect(() => {
|
|
23
|
+
return store.subscribeSyncStatus(setStatus);
|
|
24
|
+
}, [store]);
|
|
25
|
+
React.useDebugValue(`LiveStore:useSyncStatus:${status.isSynced === true ? 'synced' : 'pending'}`);
|
|
26
|
+
return status;
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=useSyncStatus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSyncStatus.js","sourceRoot":"","sources":["../src/useSyncStatus.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAIzB;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,OAA8B,EAAc,EAAE;IAC1E,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAA;IAEzB,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAa,GAAG,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC,CAAA;IAEhF,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,OAAO,KAAK,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAA;IAC7C,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;IAEX,KAAK,CAAC,aAAa,CAAC,2BAA2B,MAAM,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAA;IAEjG,OAAO,MAAM,CAAA;AACf,CAAC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,45 +1,88 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@livestore/react",
|
|
3
|
-
"version": "0.4.0-dev.
|
|
3
|
+
"version": "0.4.0-dev.23",
|
|
4
|
+
"license": "Apache-2.0",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/livestorejs/livestore.git"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"package.json",
|
|
12
|
+
"src"
|
|
13
|
+
],
|
|
4
14
|
"type": "module",
|
|
5
15
|
"sideEffects": false,
|
|
6
16
|
"exports": {
|
|
7
17
|
".": "./dist/mod.js",
|
|
8
18
|
"./experimental": "./dist/experimental/mod.js"
|
|
9
19
|
},
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"access": "public"
|
|
22
|
+
},
|
|
10
23
|
"dependencies": {
|
|
11
24
|
"@opentelemetry/api": "1.9.0",
|
|
12
|
-
"@livestore/common": "0.4.0-dev.
|
|
13
|
-
"@livestore/
|
|
14
|
-
"@livestore/livestore": "0.4.0-dev.
|
|
25
|
+
"@livestore/common": "^0.4.0-dev.23",
|
|
26
|
+
"@livestore/framework-toolkit": "^0.4.0-dev.23",
|
|
27
|
+
"@livestore/livestore": "^0.4.0-dev.23",
|
|
28
|
+
"@livestore/utils": "^0.4.0-dev.23"
|
|
15
29
|
},
|
|
16
30
|
"devDependencies": {
|
|
17
|
-
"@opentelemetry/sdk-trace-base": "2.0
|
|
18
|
-
"@testing-library/dom": "
|
|
19
|
-
"@testing-library/react": "
|
|
20
|
-
"@types/react": "19.
|
|
21
|
-
"@types/react-dom": "19.
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"react
|
|
25
|
-
"react-
|
|
26
|
-
"
|
|
27
|
-
"
|
|
31
|
+
"@opentelemetry/sdk-trace-base": "2.2.0",
|
|
32
|
+
"@testing-library/dom": "10.4.1",
|
|
33
|
+
"@testing-library/react": "16.3.1",
|
|
34
|
+
"@types/react": "19.2.7",
|
|
35
|
+
"@types/react-dom": "19.2.3",
|
|
36
|
+
"@types/react-window": "1.8.8",
|
|
37
|
+
"jsdom": "26.1.0",
|
|
38
|
+
"react": "19.2.3",
|
|
39
|
+
"react-dom": "19.2.3",
|
|
40
|
+
"react-window": "1.8.11",
|
|
41
|
+
"typescript": "5.9.3",
|
|
42
|
+
"vite": "7.3.1",
|
|
28
43
|
"vitest": "3.2.4",
|
|
29
|
-
"@livestore/adapter-web": "0.4.0-dev.
|
|
30
|
-
"@livestore/utils-dev": "0.4.0-dev.
|
|
44
|
+
"@livestore/adapter-web": "^0.4.0-dev.23",
|
|
45
|
+
"@livestore/utils-dev": "^0.4.0-dev.23"
|
|
31
46
|
},
|
|
32
|
-
"files": [
|
|
33
|
-
"package.json",
|
|
34
|
-
"src",
|
|
35
|
-
"dist"
|
|
36
|
-
],
|
|
37
|
-
"license": "Apache-2.0",
|
|
38
47
|
"peerDependencies": {
|
|
39
|
-
"
|
|
48
|
+
"@effect/ai": "^0.35.0",
|
|
49
|
+
"@effect/cli": "^0.75.1",
|
|
50
|
+
"@effect/cluster": "^0.58.2",
|
|
51
|
+
"@effect/experimental": "^0.60.0",
|
|
52
|
+
"@effect/opentelemetry": "^0.63.0",
|
|
53
|
+
"@effect/platform": "^0.96.1",
|
|
54
|
+
"@effect/platform-browser": "^0.76.0",
|
|
55
|
+
"@effect/platform-bun": "^0.89.0",
|
|
56
|
+
"@effect/platform-node": "^0.106.0",
|
|
57
|
+
"@effect/printer": "^0.49.0",
|
|
58
|
+
"@effect/printer-ansi": "^0.49.0",
|
|
59
|
+
"@effect/rpc": "^0.75.1",
|
|
60
|
+
"@effect/sql": "^0.51.1",
|
|
61
|
+
"@effect/typeclass": "^0.40.0",
|
|
62
|
+
"@effect/vitest": "^0.29.0",
|
|
63
|
+
"@opentelemetry/api": "^1.9.0",
|
|
64
|
+
"@opentelemetry/resources": "^2.2.0",
|
|
65
|
+
"@standard-schema/spec": "^1.1.0",
|
|
66
|
+
"effect": "^3.21.2",
|
|
67
|
+
"react": "^19.0.0"
|
|
40
68
|
},
|
|
41
|
-
"
|
|
42
|
-
"
|
|
69
|
+
"$genie": {
|
|
70
|
+
"source": "package.json.genie.ts",
|
|
71
|
+
"warning": "DO NOT EDIT - changes will be overwritten",
|
|
72
|
+
"workspaceClosureDirs": [
|
|
73
|
+
"packages/@livestore/adapter-web",
|
|
74
|
+
"packages/@livestore/common",
|
|
75
|
+
"packages/@livestore/common-cf",
|
|
76
|
+
"packages/@livestore/devtools-web-common",
|
|
77
|
+
"packages/@livestore/framework-toolkit",
|
|
78
|
+
"packages/@livestore/livestore",
|
|
79
|
+
"packages/@livestore/react",
|
|
80
|
+
"packages/@livestore/sqlite-wasm",
|
|
81
|
+
"packages/@livestore/utils",
|
|
82
|
+
"packages/@livestore/utils-dev",
|
|
83
|
+
"packages/@livestore/wa-sqlite",
|
|
84
|
+
"packages/@livestore/webmesh"
|
|
85
|
+
]
|
|
43
86
|
},
|
|
44
87
|
"scripts": {
|
|
45
88
|
"build": "tsc",
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
|
|
3
|
+
import type { StoreRegistry } from '@livestore/livestore'
|
|
4
|
+
|
|
5
|
+
export const StoreRegistryContext = React.createContext<StoreRegistry | undefined>(undefined)
|
|
6
|
+
|
|
7
|
+
export type StoreRegistryProviderProps = {
|
|
8
|
+
storeRegistry: StoreRegistry
|
|
9
|
+
children: React.ReactNode
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* React context provider that makes a {@link StoreRegistry} available to descendant components.
|
|
14
|
+
*
|
|
15
|
+
* Wrap your application (or a subtree) with this provider to enable {@link useStore} and
|
|
16
|
+
* {@link useStoreRegistry} hooks within that tree.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```tsx
|
|
20
|
+
* import { StoreRegistry } from '@livestore/livestore'
|
|
21
|
+
* import { StoreRegistryProvider } from '@livestore/react'
|
|
22
|
+
* import { unstable_batchedUpdates as batchUpdates } from 'react-dom'
|
|
23
|
+
*
|
|
24
|
+
* const storeRegistry = new StoreRegistry({
|
|
25
|
+
* defaultOptions: { batchUpdates }
|
|
26
|
+
* })
|
|
27
|
+
*
|
|
28
|
+
* function App() {
|
|
29
|
+
* return (
|
|
30
|
+
* <StoreRegistryProvider storeRegistry={storeRegistry}>
|
|
31
|
+
* <MyComponent />
|
|
32
|
+
* </StoreRegistryProvider>
|
|
33
|
+
* )
|
|
34
|
+
* }
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export const StoreRegistryProvider = ({ storeRegistry, children }: StoreRegistryProviderProps): React.JSX.Element => {
|
|
38
|
+
return <StoreRegistryContext value={storeRegistry}>{children}</StoreRegistryContext>
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Hook to access the {@link StoreRegistry} from context. Useful for advanced operations like preloading.
|
|
43
|
+
*
|
|
44
|
+
* @param override - Optional registry to use instead of the context value.
|
|
45
|
+
* When provided, skips context lookup entirely.
|
|
46
|
+
* @returns The registry provided by the nearest {@link StoreRegistryProvider} ancestor, or the `override` if provided.
|
|
47
|
+
* @throws Error if called outside a {@link StoreRegistryProvider} and no override is provided
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```tsx
|
|
51
|
+
* function PreloadButton({ issueId }: { issueId: string }) {
|
|
52
|
+
* const storeRegistry = useStoreRegistry()
|
|
53
|
+
*
|
|
54
|
+
* const handleMouseEnter = () => {
|
|
55
|
+
* storeRegistry.preload(issueStoreOptions(issueId))
|
|
56
|
+
* }
|
|
57
|
+
*
|
|
58
|
+
* return <button onMouseEnter={handleMouseEnter}>View Issue</button>
|
|
59
|
+
* }
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export const useStoreRegistry = (override?: StoreRegistry) => {
|
|
63
|
+
if (override !== undefined) return override
|
|
64
|
+
|
|
65
|
+
const storeRegistry = React.use(StoreRegistryContext)
|
|
66
|
+
|
|
67
|
+
if (storeRegistry == null) throw new Error('useStoreRegistry() must be used within <StoreRegistryProvider>')
|
|
68
|
+
|
|
69
|
+
return storeRegistry
|
|
70
|
+
}
|
|
@@ -8,6 +8,9 @@ exports[`useClientDocument > otel > should update the data based on component ke
|
|
|
8
8
|
"storeId": "default",
|
|
9
9
|
},
|
|
10
10
|
"children": [
|
|
11
|
+
{
|
|
12
|
+
"_name": "makeClientSessionSyncProcessor",
|
|
13
|
+
},
|
|
11
14
|
{
|
|
12
15
|
"_name": "livestore.in-memory-db:execute",
|
|
13
16
|
"attributes": {
|
|
@@ -21,29 +24,31 @@ exports[`useClientDocument > otel > should update the data based on component ke
|
|
|
21
24
|
},
|
|
22
25
|
},
|
|
23
26
|
{
|
|
24
|
-
"_name": "
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
27
|
+
"_name": "client-session-sync-processor:boot",
|
|
28
|
+
"children": [
|
|
29
|
+
{
|
|
30
|
+
"_name": "@livestore/common:LeaderSyncProcessor:push",
|
|
31
|
+
"attributes": {
|
|
32
|
+
"batch": "undefined",
|
|
33
|
+
"batchSize": 1,
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"_name": "@livestore/common:LeaderSyncProcessor:push",
|
|
38
|
+
"attributes": {
|
|
39
|
+
"batch": "undefined",
|
|
40
|
+
"batchSize": 1,
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"_name": "client-session-sync-processor:pull",
|
|
45
|
+
"attributes": {
|
|
46
|
+
"code.stacktrace": "<STACKTRACE>",
|
|
47
|
+
"span.label": "⚠︎ Interrupted",
|
|
48
|
+
"status.interrupted": true,
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
],
|
|
47
52
|
},
|
|
48
53
|
{
|
|
49
54
|
"_name": "LiveStore:commits",
|
|
@@ -194,14 +199,10 @@ exports[`useClientDocument > otel > should update the data based on component ke
|
|
|
194
199
|
},
|
|
195
200
|
"children": [
|
|
196
201
|
{
|
|
197
|
-
"_name": "client-session-sync-processor:
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
"UserInfoSet": 1
|
|
202
|
-
}",
|
|
203
|
-
"mergeResultTag": "advance",
|
|
204
|
-
},
|
|
202
|
+
"_name": "client-session-sync-processor:encode-events",
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
"_name": "client-session-sync-processor:materialize-events",
|
|
205
206
|
"children": [
|
|
206
207
|
{
|
|
207
208
|
"_name": "client-session-sync-processor:materialize-event",
|
|
@@ -220,6 +221,16 @@ exports[`useClientDocument > otel > should update the data based on component ke
|
|
|
220
221
|
},
|
|
221
222
|
],
|
|
222
223
|
},
|
|
224
|
+
{
|
|
225
|
+
"_name": "client-session-sync-processor:push",
|
|
226
|
+
"attributes": {
|
|
227
|
+
"batchSize": 1,
|
|
228
|
+
"eventCounts": "{
|
|
229
|
+
"UserInfoSet": 1
|
|
230
|
+
}",
|
|
231
|
+
"mergeResultTag": "advance",
|
|
232
|
+
},
|
|
233
|
+
},
|
|
223
234
|
],
|
|
224
235
|
},
|
|
225
236
|
{
|
|
@@ -232,14 +243,10 @@ exports[`useClientDocument > otel > should update the data based on component ke
|
|
|
232
243
|
},
|
|
233
244
|
"children": [
|
|
234
245
|
{
|
|
235
|
-
"_name": "client-session-sync-processor:
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
"UserInfoSet": 1
|
|
240
|
-
}",
|
|
241
|
-
"mergeResultTag": "advance",
|
|
242
|
-
},
|
|
246
|
+
"_name": "client-session-sync-processor:encode-events",
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
"_name": "client-session-sync-processor:materialize-events",
|
|
243
250
|
"children": [
|
|
244
251
|
{
|
|
245
252
|
"_name": "client-session-sync-processor:materialize-event",
|
|
@@ -258,6 +265,16 @@ exports[`useClientDocument > otel > should update the data based on component ke
|
|
|
258
265
|
},
|
|
259
266
|
],
|
|
260
267
|
},
|
|
268
|
+
{
|
|
269
|
+
"_name": "client-session-sync-processor:push",
|
|
270
|
+
"attributes": {
|
|
271
|
+
"batchSize": 1,
|
|
272
|
+
"eventCounts": "{
|
|
273
|
+
"UserInfoSet": 1
|
|
274
|
+
}",
|
|
275
|
+
"mergeResultTag": "advance",
|
|
276
|
+
},
|
|
277
|
+
},
|
|
261
278
|
],
|
|
262
279
|
},
|
|
263
280
|
]
|
|
@@ -271,6 +288,9 @@ exports[`useClientDocument > otel > should update the data based on component ke
|
|
|
271
288
|
"storeId": "default",
|
|
272
289
|
},
|
|
273
290
|
"children": [
|
|
291
|
+
{
|
|
292
|
+
"_name": "makeClientSessionSyncProcessor",
|
|
293
|
+
},
|
|
274
294
|
{
|
|
275
295
|
"_name": "livestore.in-memory-db:execute",
|
|
276
296
|
"attributes": {
|
|
@@ -284,29 +304,31 @@ exports[`useClientDocument > otel > should update the data based on component ke
|
|
|
284
304
|
},
|
|
285
305
|
},
|
|
286
306
|
{
|
|
287
|
-
"_name": "
|
|
288
|
-
"
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
307
|
+
"_name": "client-session-sync-processor:boot",
|
|
308
|
+
"children": [
|
|
309
|
+
{
|
|
310
|
+
"_name": "@livestore/common:LeaderSyncProcessor:push",
|
|
311
|
+
"attributes": {
|
|
312
|
+
"batch": "undefined",
|
|
313
|
+
"batchSize": 1,
|
|
314
|
+
},
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
"_name": "@livestore/common:LeaderSyncProcessor:push",
|
|
318
|
+
"attributes": {
|
|
319
|
+
"batch": "undefined",
|
|
320
|
+
"batchSize": 1,
|
|
321
|
+
},
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
"_name": "client-session-sync-processor:pull",
|
|
325
|
+
"attributes": {
|
|
326
|
+
"code.stacktrace": "<STACKTRACE>",
|
|
327
|
+
"span.label": "⚠︎ Interrupted",
|
|
328
|
+
"status.interrupted": true,
|
|
329
|
+
},
|
|
330
|
+
},
|
|
331
|
+
],
|
|
310
332
|
},
|
|
311
333
|
{
|
|
312
334
|
"_name": "LiveStore:commits",
|
|
@@ -395,14 +417,10 @@ exports[`useClientDocument > otel > should update the data based on component ke
|
|
|
395
417
|
},
|
|
396
418
|
"children": [
|
|
397
419
|
{
|
|
398
|
-
"_name": "client-session-sync-processor:
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
"UserInfoSet": 1
|
|
403
|
-
}",
|
|
404
|
-
"mergeResultTag": "advance",
|
|
405
|
-
},
|
|
420
|
+
"_name": "client-session-sync-processor:encode-events",
|
|
421
|
+
},
|
|
422
|
+
{
|
|
423
|
+
"_name": "client-session-sync-processor:materialize-events",
|
|
406
424
|
"children": [
|
|
407
425
|
{
|
|
408
426
|
"_name": "client-session-sync-processor:materialize-event",
|
|
@@ -421,6 +439,16 @@ exports[`useClientDocument > otel > should update the data based on component ke
|
|
|
421
439
|
},
|
|
422
440
|
],
|
|
423
441
|
},
|
|
442
|
+
{
|
|
443
|
+
"_name": "client-session-sync-processor:push",
|
|
444
|
+
"attributes": {
|
|
445
|
+
"batchSize": 1,
|
|
446
|
+
"eventCounts": "{
|
|
447
|
+
"UserInfoSet": 1
|
|
448
|
+
}",
|
|
449
|
+
"mergeResultTag": "advance",
|
|
450
|
+
},
|
|
451
|
+
},
|
|
424
452
|
],
|
|
425
453
|
},
|
|
426
454
|
{
|
|
@@ -433,14 +461,10 @@ exports[`useClientDocument > otel > should update the data based on component ke
|
|
|
433
461
|
},
|
|
434
462
|
"children": [
|
|
435
463
|
{
|
|
436
|
-
"_name": "client-session-sync-processor:
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
"UserInfoSet": 1
|
|
441
|
-
}",
|
|
442
|
-
"mergeResultTag": "advance",
|
|
443
|
-
},
|
|
464
|
+
"_name": "client-session-sync-processor:encode-events",
|
|
465
|
+
},
|
|
466
|
+
{
|
|
467
|
+
"_name": "client-session-sync-processor:materialize-events",
|
|
444
468
|
"children": [
|
|
445
469
|
{
|
|
446
470
|
"_name": "client-session-sync-processor:materialize-event",
|
|
@@ -459,6 +483,16 @@ exports[`useClientDocument > otel > should update the data based on component ke
|
|
|
459
483
|
},
|
|
460
484
|
],
|
|
461
485
|
},
|
|
486
|
+
{
|
|
487
|
+
"_name": "client-session-sync-processor:push",
|
|
488
|
+
"attributes": {
|
|
489
|
+
"batchSize": 1,
|
|
490
|
+
"eventCounts": "{
|
|
491
|
+
"UserInfoSet": 1
|
|
492
|
+
}",
|
|
493
|
+
"mergeResultTag": "advance",
|
|
494
|
+
},
|
|
495
|
+
},
|
|
462
496
|
],
|
|
463
497
|
},
|
|
464
498
|
]
|
|
@@ -1,110 +1,32 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import type { UnknownError } from '@livestore/common'
|
|
2
|
+
import {
|
|
3
|
+
type AppState,
|
|
4
|
+
type CreateTodoMvcStoreOptions,
|
|
5
|
+
createTodoMvcStore,
|
|
6
|
+
events,
|
|
7
|
+
type Filter,
|
|
8
|
+
schema,
|
|
9
|
+
type Todo,
|
|
10
|
+
tables,
|
|
11
|
+
} from '@livestore/framework-toolkit/testing'
|
|
12
|
+
import type { Store } from '@livestore/livestore'
|
|
13
|
+
import { Effect, type Scope } from '@livestore/utils/effect'
|
|
9
14
|
import React from 'react'
|
|
10
15
|
|
|
11
16
|
import * as LiveStoreReact from '../mod.ts'
|
|
12
17
|
|
|
13
|
-
export
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
completed: boolean
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export type Filter = 'all' | 'active' | 'completed'
|
|
20
|
-
|
|
21
|
-
export type AppState = {
|
|
22
|
-
newTodoText: string
|
|
23
|
-
filter: Filter
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const todos = State.SQLite.table({
|
|
27
|
-
name: 'todos',
|
|
28
|
-
columns: {
|
|
29
|
-
id: State.SQLite.text({ primaryKey: true }),
|
|
30
|
-
text: State.SQLite.text({ default: '', nullable: false }),
|
|
31
|
-
completed: State.SQLite.boolean({ default: false, nullable: false }),
|
|
32
|
-
},
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
const app = State.SQLite.table({
|
|
36
|
-
name: 'app',
|
|
37
|
-
columns: {
|
|
38
|
-
id: State.SQLite.text({ primaryKey: true, default: 'static' }),
|
|
39
|
-
newTodoText: State.SQLite.text({ default: '', nullable: true }),
|
|
40
|
-
filter: State.SQLite.text({ default: 'all', nullable: false }),
|
|
41
|
-
},
|
|
42
|
-
})
|
|
18
|
+
// Re-export shared types and schema
|
|
19
|
+
export { events, schema, tables }
|
|
20
|
+
export type { AppState, Filter, Todo }
|
|
43
21
|
|
|
44
|
-
|
|
45
|
-
name: 'UserInfo',
|
|
46
|
-
schema: Schema.Struct({
|
|
47
|
-
username: Schema.String,
|
|
48
|
-
text: Schema.String,
|
|
49
|
-
}),
|
|
50
|
-
default: { value: { username: '', text: '' } },
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
const AppRouterSchema = State.SQLite.clientDocument({
|
|
54
|
-
name: 'AppRouter',
|
|
55
|
-
schema: Schema.Struct({
|
|
56
|
-
currentTaskId: Schema.String.pipe(Schema.NullOr),
|
|
57
|
-
}),
|
|
58
|
-
default: {
|
|
59
|
-
value: { currentTaskId: null },
|
|
60
|
-
id: 'singleton',
|
|
61
|
-
},
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
const kv = State.SQLite.clientDocument({
|
|
65
|
-
name: 'Kv',
|
|
66
|
-
schema: Schema.Any,
|
|
67
|
-
default: { value: null },
|
|
68
|
-
})
|
|
69
|
-
|
|
70
|
-
export const events = {
|
|
71
|
-
todoCreated: Events.synced({
|
|
72
|
-
name: 'todoCreated',
|
|
73
|
-
schema: Schema.Struct({ id: Schema.String, text: Schema.String, completed: Schema.Boolean }),
|
|
74
|
-
}),
|
|
75
|
-
todoUpdated: Events.synced({
|
|
76
|
-
name: 'todoUpdated',
|
|
77
|
-
schema: Schema.Struct({
|
|
78
|
-
id: Schema.String,
|
|
79
|
-
text: Schema.String.pipe(Schema.optional),
|
|
80
|
-
completed: Schema.Boolean.pipe(Schema.optional),
|
|
81
|
-
}),
|
|
82
|
-
}),
|
|
83
|
-
AppRouterSet: AppRouterSchema.set,
|
|
84
|
-
UserInfoSet: userInfo.set,
|
|
85
|
-
KvSet: kv.set,
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const materializers = State.SQLite.materializers(events, {
|
|
89
|
-
todoCreated: ({ id, text, completed }) => todos.insert({ id, text, completed }),
|
|
90
|
-
todoUpdated: ({ id, text, completed }) => todos.update({ ...omitUndefineds({ completed, text }) }).where({ id }),
|
|
91
|
-
})
|
|
92
|
-
|
|
93
|
-
export const tables = { todos, app, userInfo, AppRouterSchema, kv }
|
|
94
|
-
|
|
95
|
-
const state = State.SQLite.makeState({ tables, materializers })
|
|
96
|
-
export const schema = makeSchema({ state, events })
|
|
97
|
-
|
|
98
|
-
export type MakeTodoMvcReactOptions = {
|
|
99
|
-
otelTracer?: otel.Tracer | undefined
|
|
100
|
-
otelContext?: otel.Context | undefined
|
|
22
|
+
export type MakeTodoMvcReactOptions = CreateTodoMvcStoreOptions & {
|
|
101
23
|
strictMode?: boolean | undefined
|
|
102
24
|
}
|
|
103
25
|
|
|
104
26
|
export const makeTodoMvcReact: (opts?: MakeTodoMvcReactOptions) => Effect.Effect<
|
|
105
27
|
{
|
|
106
28
|
wrapper: ({ children }: any) => React.JSX.Element
|
|
107
|
-
store: Store<
|
|
29
|
+
store: Store<typeof schema> & LiveStoreReact.ReactApi
|
|
108
30
|
renderCount: { readonly val: number; inc: () => void }
|
|
109
31
|
},
|
|
110
32
|
UnknownError,
|
|
@@ -116,7 +38,7 @@ export const makeTodoMvcReact: (opts?: MakeTodoMvcReactOptions) => Effect.Effect
|
|
|
116
38
|
let val = 0
|
|
117
39
|
|
|
118
40
|
const inc = () => {
|
|
119
|
-
val += strictMode ? 0.5 : 1
|
|
41
|
+
val += strictMode === true ? 0.5 : 1
|
|
120
42
|
}
|
|
121
43
|
|
|
122
44
|
return {
|
|
@@ -127,32 +49,15 @@ export const makeTodoMvcReact: (opts?: MakeTodoMvcReactOptions) => Effect.Effect
|
|
|
127
49
|
}
|
|
128
50
|
}
|
|
129
51
|
|
|
130
|
-
const store
|
|
131
|
-
schema,
|
|
132
|
-
storeId: 'default',
|
|
133
|
-
adapter: makeInMemoryAdapter(),
|
|
134
|
-
debug: { instanceId: 'test' },
|
|
135
|
-
})
|
|
52
|
+
const store = yield* createTodoMvcStore(opts)
|
|
136
53
|
|
|
137
54
|
const storeWithReactApi = LiveStoreReact.withReactApi(store)
|
|
138
55
|
|
|
139
|
-
|
|
140
|
-
const storeContext = {
|
|
141
|
-
stage: 'running' as const,
|
|
142
|
-
store: storeWithReactApi,
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
const MaybeStrictMode = strictMode ? React.StrictMode : React.Fragment
|
|
56
|
+
const MaybeStrictMode = strictMode === true ? React.StrictMode : React.Fragment
|
|
146
57
|
|
|
147
|
-
const wrapper = ({ children }: any) =>
|
|
148
|
-
<MaybeStrictMode>
|
|
149
|
-
<LiveStoreReact.LiveStoreContext.Provider value={storeContext}>
|
|
150
|
-
{children}
|
|
151
|
-
</LiveStoreReact.LiveStoreContext.Provider>
|
|
152
|
-
</MaybeStrictMode>
|
|
153
|
-
)
|
|
58
|
+
const wrapper = ({ children }: any) => <MaybeStrictMode>{children}</MaybeStrictMode>
|
|
154
59
|
|
|
155
60
|
const renderCount = makeRenderCount()
|
|
156
61
|
|
|
157
62
|
return { wrapper, store: storeWithReactApi, renderCount }
|
|
158
|
-
})
|
|
63
|
+
})
|