@livestore/livestore 0.0.12 → 0.0.14

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.
Files changed (226) hide show
  1. package/README.md +25 -28
  2. package/dist/.tsbuildinfo +1 -0
  3. package/dist/QueryCache.d.ts +20 -0
  4. package/dist/QueryCache.d.ts.map +1 -0
  5. package/dist/QueryCache.js +71 -0
  6. package/dist/QueryCache.js.map +1 -0
  7. package/dist/__tests__/react/fixture.d.ts +26 -0
  8. package/dist/__tests__/react/fixture.d.ts.map +1 -0
  9. package/dist/__tests__/react/fixture.js +60 -0
  10. package/dist/__tests__/react/fixture.js.map +1 -0
  11. package/dist/__tests__/react/useComponentState.test.d.ts +2 -0
  12. package/dist/__tests__/react/useComponentState.test.d.ts.map +1 -0
  13. package/dist/__tests__/react/useComponentState.test.js +68 -0
  14. package/dist/__tests__/react/useComponentState.test.js.map +1 -0
  15. package/dist/__tests__/react/useLQuery.test.d.ts +2 -0
  16. package/dist/__tests__/react/useLQuery.test.d.ts.map +1 -0
  17. package/dist/__tests__/react/useLQuery.test.js +38 -0
  18. package/dist/__tests__/react/useLQuery.test.js.map +1 -0
  19. package/dist/__tests__/react/useLiveStoreComponent.test.d.ts +2 -0
  20. package/dist/__tests__/react/useLiveStoreComponent.test.d.ts.map +1 -0
  21. package/dist/__tests__/react/useLiveStoreComponent.test.js +73 -0
  22. package/dist/__tests__/react/useLiveStoreComponent.test.js.map +1 -0
  23. package/dist/__tests__/react/useQuery.test.d.ts +2 -0
  24. package/dist/__tests__/react/useQuery.test.d.ts.map +1 -0
  25. package/dist/__tests__/react/useQuery.test.js +33 -0
  26. package/dist/__tests__/react/useQuery.test.js.map +1 -0
  27. package/dist/__tests__/react/utils/extractStackInfoFromStackTrace.test.d.ts +2 -0
  28. package/dist/__tests__/react/utils/extractStackInfoFromStackTrace.test.d.ts.map +1 -0
  29. package/dist/__tests__/react/utils/extractStackInfoFromStackTrace.test.js +38 -0
  30. package/dist/__tests__/react/utils/extractStackInfoFromStackTrace.test.js.map +1 -0
  31. package/dist/__tests__/reactive.test.d.ts +2 -0
  32. package/dist/__tests__/reactive.test.d.ts.map +1 -0
  33. package/dist/__tests__/reactive.test.js +271 -0
  34. package/dist/__tests__/reactive.test.js.map +1 -0
  35. package/dist/__tests__/reactiveQueries/sql.test.d.ts +2 -0
  36. package/dist/__tests__/reactiveQueries/sql.test.d.ts.map +1 -0
  37. package/dist/__tests__/reactiveQueries/sql.test.js +337 -0
  38. package/dist/__tests__/reactiveQueries/sql.test.js.map +1 -0
  39. package/dist/bounded-collections.d.ts +34 -0
  40. package/dist/bounded-collections.d.ts.map +1 -0
  41. package/dist/bounded-collections.js +103 -0
  42. package/dist/bounded-collections.js.map +1 -0
  43. package/dist/componentKey.d.ts +20 -0
  44. package/dist/componentKey.d.ts.map +1 -0
  45. package/dist/componentKey.js +3 -0
  46. package/dist/componentKey.js.map +1 -0
  47. package/dist/effect/LiveStore.d.ts +36 -0
  48. package/dist/effect/LiveStore.d.ts.map +1 -0
  49. package/dist/effect/LiveStore.js +41 -0
  50. package/dist/effect/LiveStore.js.map +1 -0
  51. package/dist/effect/index.d.ts +2 -0
  52. package/dist/effect/index.d.ts.map +1 -0
  53. package/dist/effect/index.js +2 -0
  54. package/dist/effect/index.js.map +1 -0
  55. package/dist/events.d.ts +7 -0
  56. package/dist/events.d.ts.map +1 -0
  57. package/dist/events.js +2 -0
  58. package/dist/events.js.map +1 -0
  59. package/dist/inMemoryDatabase.d.ts +56 -0
  60. package/dist/inMemoryDatabase.d.ts.map +1 -0
  61. package/dist/inMemoryDatabase.js +223 -0
  62. package/dist/inMemoryDatabase.js.map +1 -0
  63. package/dist/index.d.ts +22 -0
  64. package/dist/index.d.ts.map +1 -0
  65. package/dist/index.js +13 -0
  66. package/dist/index.js.map +1 -0
  67. package/dist/migrations.d.ts +16 -0
  68. package/dist/migrations.d.ts.map +1 -0
  69. package/dist/migrations.js +67 -0
  70. package/dist/migrations.js.map +1 -0
  71. package/dist/otel.d.ts +4 -0
  72. package/dist/otel.d.ts.map +1 -0
  73. package/dist/otel.js +6 -0
  74. package/dist/otel.js.map +1 -0
  75. package/dist/react/LiveStoreContext.d.ts +11 -0
  76. package/dist/react/LiveStoreContext.d.ts.map +1 -0
  77. package/dist/react/LiveStoreContext.js +10 -0
  78. package/dist/react/LiveStoreContext.js.map +1 -0
  79. package/dist/react/LiveStoreProvider.d.ts +20 -0
  80. package/dist/react/LiveStoreProvider.d.ts.map +1 -0
  81. package/dist/react/LiveStoreProvider.js +52 -0
  82. package/dist/react/LiveStoreProvider.js.map +1 -0
  83. package/dist/react/index.d.ts +8 -0
  84. package/dist/react/index.d.ts.map +1 -0
  85. package/dist/react/index.js +6 -0
  86. package/dist/react/index.js.map +1 -0
  87. package/dist/react/useComponentState.d.ts +50 -0
  88. package/dist/react/useComponentState.d.ts.map +1 -0
  89. package/dist/react/useComponentState.js +248 -0
  90. package/dist/react/useComponentState.js.map +1 -0
  91. package/dist/react/useGlobalQuery.d.ts +3 -0
  92. package/dist/react/useGlobalQuery.d.ts.map +1 -0
  93. package/dist/react/useGlobalQuery.js +26 -0
  94. package/dist/react/useGlobalQuery.js.map +1 -0
  95. package/dist/react/useGraphQL.d.ts +13 -0
  96. package/dist/react/useGraphQL.d.ts.map +1 -0
  97. package/dist/react/useGraphQL.js +87 -0
  98. package/dist/react/useGraphQL.js.map +1 -0
  99. package/dist/react/useLiveStoreComponent.d.ts +75 -0
  100. package/dist/react/useLiveStoreComponent.d.ts.map +1 -0
  101. package/dist/react/useLiveStoreComponent.js +361 -0
  102. package/dist/react/useLiveStoreComponent.js.map +1 -0
  103. package/dist/react/useQuery.d.ts +3 -0
  104. package/dist/react/useQuery.d.ts.map +1 -0
  105. package/dist/react/useQuery.js +42 -0
  106. package/dist/react/useQuery.js.map +1 -0
  107. package/dist/react/useTemporaryQuery.d.ts +8 -0
  108. package/dist/react/useTemporaryQuery.d.ts.map +1 -0
  109. package/dist/react/useTemporaryQuery.js +17 -0
  110. package/dist/react/useTemporaryQuery.js.map +1 -0
  111. package/dist/react/utils/extractNamesFromStackTrace.d.ts +3 -0
  112. package/dist/react/utils/extractNamesFromStackTrace.d.ts.map +1 -0
  113. package/dist/react/utils/extractNamesFromStackTrace.js +40 -0
  114. package/dist/react/utils/extractNamesFromStackTrace.js.map +1 -0
  115. package/dist/react/utils/extractStackInfoFromStackTrace.d.ts +7 -0
  116. package/dist/react/utils/extractStackInfoFromStackTrace.d.ts.map +1 -0
  117. package/dist/react/utils/extractStackInfoFromStackTrace.js +40 -0
  118. package/dist/react/utils/extractStackInfoFromStackTrace.js.map +1 -0
  119. package/dist/react/utils/useStateRefWithReactiveInput.d.ts +13 -0
  120. package/dist/react/utils/useStateRefWithReactiveInput.d.ts.map +1 -0
  121. package/dist/react/utils/useStateRefWithReactiveInput.js +38 -0
  122. package/dist/react/utils/useStateRefWithReactiveInput.js.map +1 -0
  123. package/dist/reactive.d.ts +134 -0
  124. package/dist/reactive.d.ts.map +1 -0
  125. package/dist/reactive.js +409 -0
  126. package/dist/reactive.js.map +1 -0
  127. package/dist/reactiveQueries/base-class.d.ts +32 -0
  128. package/dist/reactiveQueries/base-class.d.ts.map +1 -0
  129. package/dist/reactiveQueries/base-class.js +30 -0
  130. package/dist/reactiveQueries/base-class.js.map +1 -0
  131. package/dist/reactiveQueries/graph.d.ts +10 -0
  132. package/dist/reactiveQueries/graph.d.ts.map +1 -0
  133. package/dist/reactiveQueries/graph.js +6 -0
  134. package/dist/reactiveQueries/graph.js.map +1 -0
  135. package/dist/reactiveQueries/graphql.d.ts +42 -0
  136. package/dist/reactiveQueries/graphql.d.ts.map +1 -0
  137. package/dist/reactiveQueries/graphql.js +99 -0
  138. package/dist/reactiveQueries/graphql.js.map +1 -0
  139. package/dist/reactiveQueries/js.d.ts +23 -0
  140. package/dist/reactiveQueries/js.d.ts.map +1 -0
  141. package/dist/reactiveQueries/js.js +36 -0
  142. package/dist/reactiveQueries/js.js.map +1 -0
  143. package/dist/reactiveQueries/sql.d.ts +35 -0
  144. package/dist/reactiveQueries/sql.d.ts.map +1 -0
  145. package/dist/reactiveQueries/sql.js +97 -0
  146. package/dist/reactiveQueries/sql.js.map +1 -0
  147. package/dist/schema.d.ts +81 -0
  148. package/dist/schema.d.ts.map +1 -0
  149. package/dist/schema.js +46 -0
  150. package/dist/schema.js.map +1 -0
  151. package/dist/storage/in-memory/index.d.ts +15 -0
  152. package/dist/storage/in-memory/index.d.ts.map +1 -0
  153. package/dist/storage/in-memory/index.js +14 -0
  154. package/dist/storage/in-memory/index.js.map +1 -0
  155. package/dist/storage/index.d.ts +14 -0
  156. package/dist/storage/index.d.ts.map +1 -0
  157. package/dist/storage/index.js +9 -0
  158. package/dist/storage/index.js.map +1 -0
  159. package/dist/storage/tauri/index.d.ts +19 -0
  160. package/dist/storage/tauri/index.d.ts.map +1 -0
  161. package/dist/storage/tauri/index.js +38 -0
  162. package/dist/storage/tauri/index.js.map +1 -0
  163. package/dist/storage/utils/idb.d.ts +10 -0
  164. package/dist/storage/utils/idb.d.ts.map +1 -0
  165. package/dist/storage/utils/idb.js +58 -0
  166. package/dist/storage/utils/idb.js.map +1 -0
  167. package/dist/storage/web-worker/index.d.ts +27 -0
  168. package/dist/storage/web-worker/index.d.ts.map +1 -0
  169. package/dist/storage/web-worker/index.js +74 -0
  170. package/dist/storage/web-worker/index.js.map +1 -0
  171. package/dist/storage/web-worker/worker.d.ts +13 -0
  172. package/dist/storage/web-worker/worker.d.ts.map +1 -0
  173. package/dist/storage/web-worker/worker.js +110 -0
  174. package/dist/storage/web-worker/worker.js.map +1 -0
  175. package/dist/store.d.ts +159 -0
  176. package/dist/store.d.ts.map +1 -0
  177. package/dist/store.js +626 -0
  178. package/dist/store.js.map +1 -0
  179. package/dist/util.d.ts +28 -0
  180. package/dist/util.d.ts.map +1 -0
  181. package/dist/util.js +55 -0
  182. package/dist/util.js.map +1 -0
  183. package/package.json +47 -19
  184. package/src/QueryCache.ts +1 -1
  185. package/src/__tests__/react/fixture.tsx +35 -39
  186. package/src/__tests__/react/{useLiveStoreComponent.test.tsx → useComponentState.test.tsx} +9 -20
  187. package/src/__tests__/react/useQuery.test.tsx +48 -0
  188. package/src/__tests__/react/utils/extractStackInfoFromStackTrace.test.ts +40 -0
  189. package/src/__tests__/reactive.test.ts +194 -142
  190. package/src/__tests__/reactiveQueries/sql.test.ts +372 -0
  191. package/src/effect/LiveStore.ts +22 -31
  192. package/src/events.ts +1 -1
  193. package/src/inMemoryDatabase.ts +117 -142
  194. package/src/index.ts +18 -22
  195. package/src/migrations.ts +119 -0
  196. package/src/otel.ts +0 -11
  197. package/src/react/LiveStoreProvider.tsx +24 -23
  198. package/src/react/index.ts +12 -7
  199. package/src/react/useComponentState.ts +409 -0
  200. package/src/react/useQuery.ts +58 -0
  201. package/src/react/useTemporaryQuery.ts +21 -0
  202. package/src/react/utils/extractStackInfoFromStackTrace.ts +47 -0
  203. package/src/reactive.ts +386 -267
  204. package/src/reactiveQueries/base-class.ts +61 -39
  205. package/src/reactiveQueries/graph.ts +15 -0
  206. package/src/reactiveQueries/graphql.ts +147 -31
  207. package/src/reactiveQueries/js.ts +54 -21
  208. package/src/reactiveQueries/sql.ts +128 -37
  209. package/src/schema.ts +69 -145
  210. package/src/storage/in-memory/index.ts +21 -0
  211. package/src/storage/index.ts +27 -0
  212. package/src/{backends/tauri.ts → storage/tauri/index.ts} +14 -28
  213. package/src/storage/web-worker/index.ts +116 -0
  214. package/src/{backends/web-worker.ts → storage/web-worker/worker.ts} +17 -52
  215. package/src/store.ts +466 -457
  216. package/src/util.ts +13 -3
  217. package/tsconfig.json +1 -3
  218. package/src/backends/base.ts +0 -67
  219. package/src/backends/index.ts +0 -98
  220. package/src/backends/noop.ts +0 -32
  221. package/src/backends/web-in-memory.ts +0 -65
  222. package/src/backends/web.ts +0 -97
  223. package/src/react/useGlobalQuery.ts +0 -40
  224. package/src/react/useGraphQL.ts +0 -112
  225. package/src/react/useLiveStoreComponent.ts +0 -483
  226. /package/src/{backends → storage}/utils/idb.ts +0 -0
package/dist/util.d.ts ADDED
@@ -0,0 +1,28 @@
1
+ /// <reference lib="es2022" />
2
+ import type { Brand } from '@livestore/utils/effect';
3
+ export type ParamsObject = Record<string, SqlValue>;
4
+ export type SqlValue = string | number | Uint8Array | null;
5
+ export type Bindable = SqlValue[] | ParamsObject;
6
+ export type PreparedBindValues = Brand.Branded<Bindable, 'PreparedBindValues'>;
7
+ /**
8
+ * This is a tag function for tagged literals.
9
+ * it lets us get syntax highlighting on SQL queries in VSCode, but
10
+ * doesn't do anything at runtime.
11
+ * Code copied from: https://esdiscuss.org/topic/string-identity-template-tag
12
+ */
13
+ export declare const sql: (template: TemplateStringsArray, ...args: unknown[]) => string;
14
+ /** Prepare bind values to send to SQLite
15
+ /* Add $ to the beginning of keys; which we use as our interpolation syntax
16
+ /* We also strip out any params that aren't used in the statement,
17
+ /* because rusqlite doesn't allow unused named params
18
+ /* TODO: Search for unused params via proper parsing, not string search
19
+ **/
20
+ export declare const prepareBindValues: (values: Bindable, statement: string) => PreparedBindValues;
21
+ /**
22
+ * Use this to make assertion at end of if-else chain that all members of a
23
+ * union have been accounted for.
24
+ */
25
+ export declare function casesHandled(x: never): never;
26
+ export declare const objectToString: (error: any) => string;
27
+ export declare const isPromise: (value: any) => value is Promise<unknown>;
28
+ //# sourceMappingURL=util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":";AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAEpD,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;AACnD,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,IAAI,CAAA;AAE1D,MAAM,MAAM,QAAQ,GAAG,QAAQ,EAAE,GAAG,YAAY,CAAA;AAEhD,MAAM,MAAM,kBAAkB,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,oBAAoB,CAAC,CAAA;AAE9E;;;;;GAKG;AACH,eAAO,MAAM,GAAG,aAAc,oBAAoB,WAAW,OAAO,EAAE,KAAG,MAMxE,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,WAAY,QAAQ,aAAa,MAAM,KAAG,kBAWvE,CAAA;AAED;;;GAGG;AAEH,wBAAgB,YAAY,CAAC,CAAC,EAAE,KAAK,GAAG,KAAK,CAE5C;AAED,eAAO,MAAM,cAAc,UAAW,GAAG,KAAG,MAa3C,CAAA;AAED,eAAO,MAAM,SAAS,UAAW,GAAG,8BAAiE,CAAA"}
package/dist/util.js ADDED
@@ -0,0 +1,55 @@
1
+ /// <reference lib="es2022" />
2
+ /**
3
+ * This is a tag function for tagged literals.
4
+ * it lets us get syntax highlighting on SQL queries in VSCode, but
5
+ * doesn't do anything at runtime.
6
+ * Code copied from: https://esdiscuss.org/topic/string-identity-template-tag
7
+ */
8
+ export const sql = (template, ...args) => {
9
+ let str = '';
10
+ for (const [i, arg] of args.entries()) {
11
+ str += template[i] + String(arg);
12
+ }
13
+ return str + template.at(-1);
14
+ };
15
+ /** Prepare bind values to send to SQLite
16
+ /* Add $ to the beginning of keys; which we use as our interpolation syntax
17
+ /* We also strip out any params that aren't used in the statement,
18
+ /* because rusqlite doesn't allow unused named params
19
+ /* TODO: Search for unused params via proper parsing, not string search
20
+ **/
21
+ export const prepareBindValues = (values, statement) => {
22
+ if (Array.isArray(values))
23
+ return values;
24
+ const result = {};
25
+ for (const [key, value] of Object.entries(values)) {
26
+ if (statement.includes(key)) {
27
+ result[`$${key}`] = value;
28
+ }
29
+ }
30
+ return result;
31
+ };
32
+ /**
33
+ * Use this to make assertion at end of if-else chain that all members of a
34
+ * union have been accounted for.
35
+ */
36
+ /* eslint-disable-next-line prefer-arrow/prefer-arrow-functions */
37
+ export function casesHandled(x) {
38
+ throw new Error(`A case was not handled for value: ${objectToString(x)}`);
39
+ }
40
+ export const objectToString = (error) => {
41
+ const stack = typeof process !== 'undefined' && process.env.CL_DEBUG ? error.stack : undefined;
42
+ const str = error.toString();
43
+ const stackStr = stack ? `\n${stack}` : '';
44
+ if (str !== '[object Object]')
45
+ return str + stackStr;
46
+ try {
47
+ return JSON.stringify({ ...error, stack }, null, 2);
48
+ }
49
+ catch (e) {
50
+ console.log(error);
51
+ return 'Error while printing error: ' + e;
52
+ }
53
+ };
54
+ export const isPromise = (value) => typeof value?.then === 'function';
55
+ //# sourceMappingURL=util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAW9B;;;;;GAKG;AACH,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,QAA8B,EAAE,GAAG,IAAe,EAAU,EAAE;IAChF,IAAI,GAAG,GAAG,EAAE,CAAA;IACZ,KAAK,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE;QACrC,GAAG,IAAI,QAAQ,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;KACjC;IACD,OAAO,GAAG,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;AAC9B,CAAC,CAAA;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,MAAgB,EAAE,SAAiB,EAAsB,EAAE;IAC3F,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,MAA4B,CAAA;IAE9D,MAAM,MAAM,GAAiB,EAAE,CAAA;IAC/B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;QACjD,IAAI,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;YAC3B,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC,GAAG,KAAK,CAAA;SAC1B;KACF;IAED,OAAO,MAA4B,CAAA;AACrC,CAAC,CAAA;AAED;;;GAGG;AACH,kEAAkE;AAClE,MAAM,UAAU,YAAY,CAAC,CAAQ;IACnC,MAAM,IAAI,KAAK,CAAC,qCAAqC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;AAC3E,CAAC;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAU,EAAU,EAAE;IACnD,MAAM,KAAK,GAAG,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAA;IAC9F,MAAM,GAAG,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAA;IAC5B,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;IAC1C,IAAI,GAAG,KAAK,iBAAiB;QAAE,OAAO,GAAG,GAAG,QAAQ,CAAA;IAEpD,IAAI;QACF,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;KACpD;IAAC,OAAO,CAAM,EAAE;QACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QAElB,OAAO,8BAA8B,GAAG,CAAC,CAAA;KAC1C;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,KAAU,EAA6B,EAAE,CAAC,OAAO,KAAK,EAAE,IAAI,KAAK,UAAU,CAAA"}
package/package.json CHANGED
@@ -1,15 +1,36 @@
1
1
  {
2
2
  "name": "@livestore/livestore",
3
- "version": "0.0.12",
3
+ "version": "0.0.14",
4
4
  "type": "module",
5
- "publishConfig": {
6
- "access": "public"
7
- },
8
5
  "exports": {
9
- ".": "./dist/index.js",
10
- "./react": "./dist/react/index.js",
11
- "./effect": "./dist/effect/index.js",
12
- "./util": "./dist/util.js"
6
+ ".": {
7
+ "types": "./dist/index.d.ts",
8
+ "default": "./dist/index.js"
9
+ },
10
+ "./storage/web-worker": {
11
+ "types": "./dist/storage/web-worker/index.d.ts",
12
+ "default": "./dist/storage/web-worker/index.js"
13
+ },
14
+ "./storage/in-memory": {
15
+ "types": "./dist/storage/in-memory/index.d.ts",
16
+ "default": "./dist/storage/in-memory/index.js"
17
+ },
18
+ "./storage/tauri": {
19
+ "types": "./dist/storage/tauri/index.d.ts",
20
+ "default": "./dist/storage/tauri/index.js"
21
+ },
22
+ "./react": {
23
+ "types": "./dist/react/index.d.ts",
24
+ "default": "./dist/react/index.js"
25
+ },
26
+ "./effect": {
27
+ "types": "./dist/effect/index.d.ts",
28
+ "default": "./dist/effect/index.js"
29
+ },
30
+ "./util": {
31
+ "types": "./dist/util.d.ts",
32
+ "default": "./dist/util.js"
33
+ }
13
34
  },
14
35
  "types": "./dist/index.d.ts",
15
36
  "typesVersions": {
@@ -34,11 +55,27 @@
34
55
  "@livestore/utils": "workspace:*",
35
56
  "@opentelemetry/api": "^1.6.0",
36
57
  "comlink": "^4.4.1",
58
+ "effect-db-schema": "workspace:*",
37
59
  "graphql": "^16.8.1",
38
60
  "lodash-es": "^4.17.21",
39
61
  "sqlite-esm": "3.42.0-build6",
40
62
  "uuid": "^9.0.1"
41
63
  },
64
+ "devDependencies": {
65
+ "@tauri-apps/api": "^1.5.0",
66
+ "@opentelemetry/sdk-trace-base": "1.17.1",
67
+ "@testing-library/react": "^14.0.0",
68
+ "@types/lodash-es": "^4.17.9",
69
+ "@types/react": "^18.2.28",
70
+ "@types/react-dom": "^18.2.13",
71
+ "@types/uuid": "^9.0.5",
72
+ "jsdom": "^22.1.0",
73
+ "react": "^18.2.0",
74
+ "react-dom": "^18.2.0",
75
+ "typescript": "5.2.2",
76
+ "vite": "4.4.11",
77
+ "vitest": "^0.34.6"
78
+ },
42
79
  "peerDependencies": {
43
80
  "@tauri-apps/api": "^1.4.0",
44
81
  "react": "^18",
@@ -49,16 +86,7 @@
49
86
  "optional": true
50
87
  }
51
88
  },
52
- "devDependencies": {
53
- "@tauri-apps/api": "^1.4.0",
54
- "@testing-library/react": "^14.0.0",
55
- "@types/lodash-es": "^4.17.9",
56
- "@types/uuid": "^9.0.4",
57
- "jsdom": "^22.1.0",
58
- "react": "^18.2.0",
59
- "react-dom": "^18.2.0",
60
- "typescript": "5.2.2",
61
- "vite": "4.4.9",
62
- "vitest": "^0.34.6"
89
+ "publishConfig": {
90
+ "access": "public"
63
91
  }
64
92
  }
package/src/QueryCache.ts CHANGED
@@ -38,7 +38,7 @@ export default class QueryCache {
38
38
  return this.#entries.get(key)
39
39
  }
40
40
 
41
- set = (queriedTables: string[], key: CacheKey, results: any) => {
41
+ set = (queriedTables: ReadonlyArray<string>, key: CacheKey, results: any) => {
42
42
  this.#entries.set(key, results)
43
43
  for (const table of queriedTables) {
44
44
  let keys = this.#dependencies.get(table)
@@ -1,9 +1,11 @@
1
- import { mapObjectValues } from '@livestore/utils'
1
+ import type * as otel from '@opentelemetry/api'
2
2
  import React from 'react'
3
+ import initSqlite3Wasm from 'sqlite-esm'
3
4
 
4
5
  import * as LiveStore from '../../index.js'
5
6
  import { sql } from '../../index.js'
6
7
  import * as LiveStoreReact from '../../react/index.js'
8
+ import { InMemoryStorage } from '../../storage/in-memory/index.js'
7
9
 
8
10
  export type Todo = {
9
11
  id: string
@@ -18,31 +20,22 @@ export type AppState = {
18
20
  filter: Filter
19
21
  }
20
22
 
21
- const appState: LiveStore.QueryDefinition = (store) =>
22
- store.querySQL<AppState>(() => `select newTodoText, filter from app;`, { queriedTables: ['app'] }).getFirstRow()
23
+ // const appState: LiveStore.QueryDefinition = (store) =>
24
+ // store.querySQL<AppState>(() => `select newTodoText, filter from app;`, { queriedTables: ['app'] }).getFirstRow()
23
25
 
24
- export const globalQueryDefs = {
25
- appState,
26
- }
27
-
28
- export const schema = LiveStore.defineSchema({
26
+ export const schema = LiveStore.makeSchema({
29
27
  tables: {
30
- todos: {
31
- columns: {
32
- id: { type: 'text', primaryKey: true },
33
- text: { type: 'text', default: '', nullable: false },
34
- completed: { type: 'boolean', default: false, nullable: false },
35
- },
36
- },
37
- app: {
38
- columns: {
39
- id: { type: 'text', primaryKey: true },
40
- newTodoText: { type: 'text', default: '', nullable: true },
41
- filter: { type: 'text', default: 'all', nullable: false },
42
- },
43
- },
28
+ todos: LiveStore.DbSchema.table('todos', {
29
+ id: LiveStore.DbSchema.text({ primaryKey: true }),
30
+ text: LiveStore.DbSchema.text({ default: '', nullable: false }),
31
+ completed: LiveStore.DbSchema.boolean({ default: false, nullable: false }),
32
+ }),
33
+ app: LiveStore.DbSchema.table('app', {
34
+ id: LiveStore.DbSchema.text({ primaryKey: true }),
35
+ newTodoText: LiveStore.DbSchema.text({ default: '', nullable: true }),
36
+ filter: LiveStore.DbSchema.text({ default: 'all', nullable: false }),
37
+ }),
44
38
  },
45
- materializedViews: {},
46
39
  actions: {
47
40
  // TODO: fix these actions to make them have write annotatinos
48
41
  addTodo: {
@@ -62,29 +55,32 @@ export const schema = LiveStore.defineSchema({
62
55
  },
63
56
  })
64
57
 
65
- export const makeTodoMvc = async () => {
66
- type UserInfoComponentState = { username: string }
58
+ export const makeTodoMvc = async ({
59
+ otelTracer,
60
+ otelContext,
61
+ }: {
62
+ otelTracer?: otel.Tracer
63
+ otelContext?: otel.Context
64
+ } = {}) => {
65
+ const AppSchema = LiveStore.defineComponentStateSchema('UserInfo', {
66
+ username: LiveStore.DbSchema.text({ default: '' }),
67
+ })
67
68
 
68
- const AppSchema = LiveStore.defineComponentStateSchema<UserInfoComponentState>({
69
- componentType: 'UserInfo',
70
- columns: {
71
- username: { type: 'text', default: '' },
72
- },
69
+ const sqlite3 = await initSqlite3Wasm({
70
+ print: (message) => console.log(`[livestore sqlite] ${message}`),
71
+ printErr: (message) => console.error(`[livestore sqlite] ${message}`),
73
72
  })
74
73
 
75
74
  const store = await LiveStore.createStore({
76
75
  schema,
77
- backendOptions: { type: 'web-in-memory' },
78
- boot: async (backend) => {
79
- backend.execute(sql`INSERT INTO app (newTodoText, filter) VALUES ('', 'all');`)
80
- // NOTE we can't insert into components__UserInfo yet because the table doesn't exist yet
81
- // backend.execute(sql`INSERT INTO components__UserInfo (id, username) VALUES ('u1', 'username_u1');`)
82
- // backend.execute(sql`INSERT INTO components__UserInfo (id, username) VALUES ('u2', 'username_u2');`)
83
- },
76
+ loadStorage: () => InMemoryStorage.load(),
77
+ boot: (db) => db.execute(sql`INSERT OR IGNORE INTO app (id, newTodoText, filter) VALUES ('static', '', 'all');`),
78
+ sqlite3,
79
+ otelTracer,
80
+ otelRootSpanContext: otelContext,
84
81
  })
85
82
 
86
- const globalQueries = mapObjectValues(globalQueryDefs, (_, queryDef) => queryDef(store))
87
- const storeContext: LiveStore.LiveStoreContext = { store, globalQueries }
83
+ const storeContext: LiveStore.LiveStoreContext = { store }
88
84
 
89
85
  const wrapper = ({ children }: any) => (
90
86
  <LiveStoreReact.LiveStoreContext.Provider value={storeContext}>{children}</LiveStoreReact.LiveStoreContext.Provider>
@@ -5,7 +5,7 @@ import { sql } from '../../index.js'
5
5
  import * as LiveStoreReact from '../../react/index.js'
6
6
  import { makeTodoMvc } from './fixture.js'
7
7
 
8
- describe('useLiveStoreComponent', () => {
8
+ describe('useComponentState', () => {
9
9
  it('should update the data based on component key', async () => {
10
10
  let renderCount = 0
11
11
 
@@ -15,10 +15,9 @@ describe('useLiveStoreComponent', () => {
15
15
  (userId: string) => {
16
16
  renderCount++
17
17
 
18
- return LiveStoreReact.useLiveStoreComponent({
19
- stateSchema: AppSchema,
18
+ return LiveStoreReact.useComponentState({
19
+ schema: AppSchema,
20
20
  componentKey: { name: 'UserInfo', id: userId },
21
- queries: () => ({}),
22
21
  })
23
22
  },
24
23
  { wrapper, initialProps: 'u1' },
@@ -48,10 +47,9 @@ describe('useLiveStoreComponent', () => {
48
47
  (userId: string) => {
49
48
  renderCount++
50
49
 
51
- return LiveStoreReact.useLiveStoreComponent({
52
- stateSchema: AppSchema,
50
+ return LiveStoreReact.useComponentState({
51
+ schema: AppSchema,
53
52
  componentKey: { name: 'UserInfo', id: userId },
54
- queries: () => ({}),
55
53
  })
56
54
  },
57
55
  { wrapper, initialProps: 'u1' },
@@ -61,13 +59,7 @@ describe('useLiveStoreComponent', () => {
61
59
  expect(result.current.state.username).toBe('')
62
60
  expect(renderCount).toBe(1)
63
61
 
64
- act(() => {
65
- result.current.setState.username('username_u1_hello')
66
- })
67
-
68
- // act(() => {
69
- // store.execute(sql`UPDATE components__UserInfo SET username = 'username_u1_hello' WHERE id = 'u1';`)
70
- // })
62
+ act(() => result.current.setState.username('username_u1_hello'))
71
63
 
72
64
  expect(result.current.state.id).toBe('u1')
73
65
  expect(result.current.state.username).toBe('username_u1_hello')
@@ -83,10 +75,9 @@ describe('useLiveStoreComponent', () => {
83
75
  (userId: string) => {
84
76
  renderCount++
85
77
 
86
- return LiveStoreReact.useLiveStoreComponent({
87
- stateSchema: AppSchema,
78
+ return LiveStoreReact.useComponentState({
79
+ schema: AppSchema,
88
80
  componentKey: { name: 'UserInfo', id: userId },
89
- queries: () => ({}),
90
81
  })
91
82
  },
92
83
  { wrapper, initialProps: 'u1' },
@@ -96,9 +87,7 @@ describe('useLiveStoreComponent', () => {
96
87
  expect(result.current.state.username).toBe('')
97
88
  expect(renderCount).toBe(1)
98
89
 
99
- act(() => {
100
- result.current.setState.username('username_u1_hello')
101
- })
90
+ act(() => result.current.setState.username('username_u1_hello'))
102
91
 
103
92
  act(() => {
104
93
  void store.execute(sql`UPDATE components__UserInfo SET username = 'username_u1_hello' WHERE id = 'u1';`)
@@ -0,0 +1,48 @@
1
+ import { act, renderHook } from '@testing-library/react'
2
+ import { describe, expect, it } from 'vitest'
3
+
4
+ import * as LiveStoreReact from '../../react/index.js'
5
+ import { LiveStoreSQLQuery } from '../../reactiveQueries/sql.js'
6
+ import { sql } from '../../util.js'
7
+ import type { Todo } from './fixture.js'
8
+ import { makeTodoMvc } from './fixture.js'
9
+
10
+ const query = new LiveStoreSQLQuery<Todo>({
11
+ label: 'todo',
12
+ genQueryString: `select * from todos`,
13
+ queriedTables: ['todos'],
14
+ })
15
+
16
+ describe('useQuery', () => {
17
+ it('simple', async () => {
18
+ let renderCount = 0
19
+
20
+ const { wrapper, store } = await makeTodoMvc()
21
+
22
+ const { result } = renderHook(
23
+ () => {
24
+ renderCount++
25
+
26
+ return LiveStoreReact.useQuery(query)
27
+ },
28
+ { wrapper },
29
+ )
30
+
31
+ expect(result.current.length).toBe(0)
32
+ expect(renderCount).toBe(1)
33
+
34
+ act(() =>
35
+ store.applyEvent('RawSql', {
36
+ sql: sql`INSERT INTO todos (id, text, completed) VALUES ('t1', 'buy milk', 0);`,
37
+ bindValues: {},
38
+ writeTables: ['todos'],
39
+ }),
40
+ )
41
+
42
+ expect(result.current.length).toBe(1)
43
+ expect(result.current[0]!.text).toBe('buy milk')
44
+ expect(renderCount).toBe(2)
45
+ })
46
+ })
47
+
48
+ // TODO write tests that use the same query in multiple components at the same time with different bind values
@@ -0,0 +1,40 @@
1
+ import { expect, it } from 'vitest'
2
+
3
+ import { extractStackInfoFromStackTrace } from '../../../react/utils/extractStackInfoFromStackTrace.js'
4
+
5
+ it('RouteLink stacktrace', async () => {
6
+ const stackTrace = `\
7
+ Error
8
+ at https://localhost:8081/@fs/Users/schickling/Code/overtone/submodules/livestore/packages/@livestore/livestore/dist/react/useQuery.js?t=1699550216884:18:23
9
+ at mountMemo (https://localhost:8081/node_modules/.vite-web/deps/chunk-M23HUTQV.js?v=3eb66ed6:12817:27)
10
+ at Object.useMemo (https://localhost:8081/node_modules/.vite-web/deps/chunk-M23HUTQV.js?v=3eb66ed6:13141:24)
11
+ at Object.useMemo (https://localhost:8081/node_modules/.vite-web/deps/chunk-4WADDZ2G.js?v=3eb66ed6:1094:29)
12
+ at useQuery (https://localhost:8081/@fs/Users/schickling/Code/overtone/submodules/livestore/packages/@livestore/livestore/dist/react/useQuery.js?t=1699550216884:13:33)
13
+ at useAppState (https://localhost:8081/src/db/AppState.ts?t=1699550216884:17:34)
14
+ at useRoute (https://localhost:8081/src/db/AppState.ts?t=1699550216884:74:22)
15
+ at RouteLink (https://localhost:8081/src/components/Link.tsx?t=1699550216884:36:7)
16
+ at renderWithHooks (https://localhost:8081/node_modules/.vite-web/deps/chunk-M23HUTQV.js?v=3eb66ed6:12171:26)
17
+ at mountIndeterminateComponent (https://localhost:8081/node_modules/.vite-web/deps/chunk-M23HUTQV.js?v=3eb66ed6:14921:21)
18
+ `
19
+
20
+ expect(extractStackInfoFromStackTrace(stackTrace)).toMatchInlineSnapshot(`
21
+ [
22
+ {
23
+ "filePath": "https://localhost:8081/src/components/Link.tsx?t=1699550216884:36:7",
24
+ "name": "RouteLink",
25
+ },
26
+ {
27
+ "filePath": "https://localhost:8081/src/db/AppState.ts?t=1699550216884:74:22",
28
+ "name": "useRoute",
29
+ },
30
+ {
31
+ "filePath": "https://localhost:8081/src/db/AppState.ts?t=1699550216884:17:34",
32
+ "name": "useAppState",
33
+ },
34
+ {
35
+ "filePath": "https://localhost:8081/@fs/Users/schickling/Code/overtone/submodules/livestore/packages/@livestore/livestore/dist/react/useQuery.js?t=1699550216884:13:33",
36
+ "name": "useQuery",
37
+ },
38
+ ]
39
+ `)
40
+ })