syncorejs 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (227) hide show
  1. package/README.md +30 -0
  2. package/dist/_vendor/core/_virtual/_rolldown/runtime.mjs +27 -0
  3. package/dist/_vendor/core/cli.d.mts +5 -0
  4. package/dist/_vendor/core/cli.d.mts.map +1 -0
  5. package/dist/_vendor/core/cli.mjs +1196 -0
  6. package/dist/_vendor/core/cli.mjs.map +1 -0
  7. package/dist/_vendor/core/index.d.mts +7 -0
  8. package/dist/_vendor/core/index.mjs +25 -0
  9. package/dist/_vendor/core/index.mjs.map +1 -0
  10. package/dist/_vendor/core/runtime/devtools.d.mts +15 -0
  11. package/dist/_vendor/core/runtime/devtools.d.mts.map +1 -0
  12. package/dist/_vendor/core/runtime/devtools.mjs +300 -0
  13. package/dist/_vendor/core/runtime/devtools.mjs.map +1 -0
  14. package/dist/_vendor/core/runtime/functions.d.mts +123 -0
  15. package/dist/_vendor/core/runtime/functions.d.mts.map +1 -0
  16. package/dist/_vendor/core/runtime/functions.mjs +71 -0
  17. package/dist/_vendor/core/runtime/functions.mjs.map +1 -0
  18. package/dist/_vendor/core/runtime/id.d.mts +13 -0
  19. package/dist/_vendor/core/runtime/id.d.mts.map +1 -0
  20. package/dist/_vendor/core/runtime/id.mjs +28 -0
  21. package/dist/_vendor/core/runtime/id.mjs.map +1 -0
  22. package/dist/_vendor/core/runtime/runtime.d.mts +370 -0
  23. package/dist/_vendor/core/runtime/runtime.d.mts.map +1 -0
  24. package/dist/_vendor/core/runtime/runtime.mjs +1143 -0
  25. package/dist/_vendor/core/runtime/runtime.mjs.map +1 -0
  26. package/dist/_vendor/devtools-protocol/index.d.ts +230 -0
  27. package/dist/_vendor/devtools-protocol/index.d.ts.map +1 -0
  28. package/dist/_vendor/devtools-protocol/index.js +0 -0
  29. package/dist/_vendor/next/config.d.ts +17 -0
  30. package/dist/_vendor/next/config.d.ts.map +1 -0
  31. package/dist/_vendor/next/config.js +73 -0
  32. package/dist/_vendor/next/config.js.map +1 -0
  33. package/dist/_vendor/next/index.d.ts +80 -0
  34. package/dist/_vendor/next/index.d.ts.map +1 -0
  35. package/dist/_vendor/next/index.js +81 -0
  36. package/dist/_vendor/next/index.js.map +1 -0
  37. package/dist/_vendor/platform-expo/index.d.ts +97 -0
  38. package/dist/_vendor/platform-expo/index.d.ts.map +1 -0
  39. package/dist/_vendor/platform-expo/index.js +197 -0
  40. package/dist/_vendor/platform-expo/index.js.map +1 -0
  41. package/dist/_vendor/platform-expo/react.d.ts +26 -0
  42. package/dist/_vendor/platform-expo/react.d.ts.map +1 -0
  43. package/dist/_vendor/platform-expo/react.js +30 -0
  44. package/dist/_vendor/platform-expo/react.js.map +1 -0
  45. package/dist/_vendor/platform-node/index.d.mts +145 -0
  46. package/dist/_vendor/platform-node/index.d.mts.map +1 -0
  47. package/dist/_vendor/platform-node/index.mjs +405 -0
  48. package/dist/_vendor/platform-node/index.mjs.map +1 -0
  49. package/dist/_vendor/platform-node/ipc-react.d.mts +25 -0
  50. package/dist/_vendor/platform-node/ipc-react.d.mts.map +1 -0
  51. package/dist/_vendor/platform-node/ipc-react.mjs +21 -0
  52. package/dist/_vendor/platform-node/ipc-react.mjs.map +1 -0
  53. package/dist/_vendor/platform-node/ipc.d.mts +75 -0
  54. package/dist/_vendor/platform-node/ipc.d.mts.map +1 -0
  55. package/dist/_vendor/platform-node/ipc.mjs +343 -0
  56. package/dist/_vendor/platform-node/ipc.mjs.map +1 -0
  57. package/dist/_vendor/platform-web/index.d.ts +123 -0
  58. package/dist/_vendor/platform-web/index.d.ts.map +1 -0
  59. package/dist/_vendor/platform-web/index.js +309 -0
  60. package/dist/_vendor/platform-web/index.js.map +1 -0
  61. package/dist/_vendor/platform-web/indexeddb.d.ts +25 -0
  62. package/dist/_vendor/platform-web/indexeddb.d.ts.map +1 -0
  63. package/dist/_vendor/platform-web/indexeddb.js +125 -0
  64. package/dist/_vendor/platform-web/indexeddb.js.map +1 -0
  65. package/dist/_vendor/platform-web/opfs.d.ts +27 -0
  66. package/dist/_vendor/platform-web/opfs.d.ts.map +1 -0
  67. package/dist/_vendor/platform-web/opfs.js +146 -0
  68. package/dist/_vendor/platform-web/opfs.js.map +1 -0
  69. package/dist/_vendor/platform-web/persistence.d.ts +27 -0
  70. package/dist/_vendor/platform-web/persistence.d.ts.map +1 -0
  71. package/dist/_vendor/platform-web/persistence.js +23 -0
  72. package/dist/_vendor/platform-web/persistence.js.map +1 -0
  73. package/dist/_vendor/platform-web/react.d.ts +35 -0
  74. package/dist/_vendor/platform-web/react.d.ts.map +1 -0
  75. package/dist/_vendor/platform-web/react.js +42 -0
  76. package/dist/_vendor/platform-web/react.js.map +1 -0
  77. package/dist/_vendor/platform-web/sqljs.js +133 -0
  78. package/dist/_vendor/platform-web/sqljs.js.map +1 -0
  79. package/dist/_vendor/platform-web/worker.d.ts +78 -0
  80. package/dist/_vendor/platform-web/worker.d.ts.map +1 -0
  81. package/dist/_vendor/platform-web/worker.js +307 -0
  82. package/dist/_vendor/platform-web/worker.js.map +1 -0
  83. package/dist/_vendor/react/index.d.ts +58 -0
  84. package/dist/_vendor/react/index.d.ts.map +1 -0
  85. package/dist/_vendor/react/index.js +151 -0
  86. package/dist/_vendor/react/index.js.map +1 -0
  87. package/dist/_vendor/schema/definition.d.ts +98 -0
  88. package/dist/_vendor/schema/definition.d.ts.map +1 -0
  89. package/dist/_vendor/schema/definition.js +84 -0
  90. package/dist/_vendor/schema/definition.js.map +1 -0
  91. package/dist/_vendor/schema/index.d.ts +4 -0
  92. package/dist/_vendor/schema/index.js +4 -0
  93. package/dist/_vendor/schema/planner.d.ts +42 -0
  94. package/dist/_vendor/schema/planner.d.ts.map +1 -0
  95. package/dist/_vendor/schema/planner.js +131 -0
  96. package/dist/_vendor/schema/planner.js.map +1 -0
  97. package/dist/_vendor/schema/validators.d.ts +194 -0
  98. package/dist/_vendor/schema/validators.d.ts.map +1 -0
  99. package/dist/_vendor/schema/validators.js +158 -0
  100. package/dist/_vendor/schema/validators.js.map +1 -0
  101. package/dist/_vendor/svelte/index.d.ts +43 -0
  102. package/dist/_vendor/svelte/index.d.ts.map +1 -0
  103. package/dist/_vendor/svelte/index.js +75 -0
  104. package/dist/_vendor/svelte/index.js.map +1 -0
  105. package/dist/browser-react.d.ts +2 -0
  106. package/dist/browser-react.js +2 -0
  107. package/dist/browser.d.ts +12 -0
  108. package/dist/browser.d.ts.map +1 -0
  109. package/dist/browser.js +10 -0
  110. package/dist/browser.js.map +1 -0
  111. package/dist/cli.d.ts +2 -0
  112. package/dist/cli.js +11 -0
  113. package/dist/cli.js.map +1 -0
  114. package/dist/core/src/cli.d.ts +5 -0
  115. package/dist/core/src/cli.d.ts.map +1 -0
  116. package/dist/core/src/cli.js +1196 -0
  117. package/dist/core/src/cli.js.map +1 -0
  118. package/dist/core/src/index.js +7 -0
  119. package/dist/core/src/runtime/devtools.d.ts +7 -0
  120. package/dist/core/src/runtime/devtools.d.ts.map +1 -0
  121. package/dist/core/src/runtime/devtools.js +300 -0
  122. package/dist/core/src/runtime/devtools.js.map +1 -0
  123. package/dist/core/src/runtime/functions.d.ts +123 -0
  124. package/dist/core/src/runtime/functions.d.ts.map +1 -0
  125. package/dist/core/src/runtime/functions.js +71 -0
  126. package/dist/core/src/runtime/functions.js.map +1 -0
  127. package/dist/core/src/runtime/id.d.ts +13 -0
  128. package/dist/core/src/runtime/id.d.ts.map +1 -0
  129. package/dist/core/src/runtime/id.js +28 -0
  130. package/dist/core/src/runtime/id.js.map +1 -0
  131. package/dist/core/src/runtime/runtime.d.ts +371 -0
  132. package/dist/core/src/runtime/runtime.d.ts.map +1 -0
  133. package/dist/core/src/runtime/runtime.js +1143 -0
  134. package/dist/core/src/runtime/runtime.js.map +1 -0
  135. package/dist/devtools-protocol/src/index.d.ts +201 -0
  136. package/dist/devtools-protocol/src/index.d.ts.map +1 -0
  137. package/dist/expo-react.d.ts +2 -0
  138. package/dist/expo-react.js +2 -0
  139. package/dist/expo.d.ts +2 -0
  140. package/dist/expo.js +2 -0
  141. package/dist/index.d.ts +7 -0
  142. package/dist/index.js +8 -0
  143. package/dist/next/src/config.d.ts +17 -0
  144. package/dist/next/src/config.d.ts.map +1 -0
  145. package/dist/next/src/config.js +73 -0
  146. package/dist/next/src/config.js.map +1 -0
  147. package/dist/next/src/index.d.ts +80 -0
  148. package/dist/next/src/index.d.ts.map +1 -0
  149. package/dist/next/src/index.js +82 -0
  150. package/dist/next/src/index.js.map +1 -0
  151. package/dist/next-config.d.ts +2 -0
  152. package/dist/next-config.js +2 -0
  153. package/dist/next.d.ts +3 -0
  154. package/dist/next.js +3 -0
  155. package/dist/node-ipc-react.d.ts +2 -0
  156. package/dist/node-ipc-react.js +2 -0
  157. package/dist/node-ipc.d.ts +2 -0
  158. package/dist/node-ipc.js +2 -0
  159. package/dist/node.d.ts +4 -0
  160. package/dist/node.js +3 -0
  161. package/dist/platform-expo/src/index.d.ts +96 -0
  162. package/dist/platform-expo/src/index.d.ts.map +1 -0
  163. package/dist/platform-expo/src/index.js +198 -0
  164. package/dist/platform-expo/src/index.js.map +1 -0
  165. package/dist/platform-expo/src/react.d.ts +26 -0
  166. package/dist/platform-expo/src/react.d.ts.map +1 -0
  167. package/dist/platform-expo/src/react.js +30 -0
  168. package/dist/platform-expo/src/react.js.map +1 -0
  169. package/dist/platform-node/src/index.d.ts +145 -0
  170. package/dist/platform-node/src/index.d.ts.map +1 -0
  171. package/dist/platform-node/src/index.js +407 -0
  172. package/dist/platform-node/src/index.js.map +1 -0
  173. package/dist/platform-node/src/ipc-react.d.ts +25 -0
  174. package/dist/platform-node/src/ipc-react.d.ts.map +1 -0
  175. package/dist/platform-node/src/ipc-react.js +21 -0
  176. package/dist/platform-node/src/ipc-react.js.map +1 -0
  177. package/dist/platform-node/src/ipc.d.ts +76 -0
  178. package/dist/platform-node/src/ipc.d.ts.map +1 -0
  179. package/dist/platform-node/src/ipc.js +344 -0
  180. package/dist/platform-node/src/ipc.js.map +1 -0
  181. package/dist/platform-web/src/index.d.ts +106 -0
  182. package/dist/platform-web/src/index.d.ts.map +1 -0
  183. package/dist/platform-web/src/index.js +311 -0
  184. package/dist/platform-web/src/index.js.map +1 -0
  185. package/dist/platform-web/src/indexeddb.js +125 -0
  186. package/dist/platform-web/src/indexeddb.js.map +1 -0
  187. package/dist/platform-web/src/opfs.js +146 -0
  188. package/dist/platform-web/src/opfs.js.map +1 -0
  189. package/dist/platform-web/src/persistence.d.ts +20 -0
  190. package/dist/platform-web/src/persistence.d.ts.map +1 -0
  191. package/dist/platform-web/src/persistence.js +23 -0
  192. package/dist/platform-web/src/persistence.js.map +1 -0
  193. package/dist/platform-web/src/react.d.ts +35 -0
  194. package/dist/platform-web/src/react.d.ts.map +1 -0
  195. package/dist/platform-web/src/react.js +42 -0
  196. package/dist/platform-web/src/react.js.map +1 -0
  197. package/dist/platform-web/src/sqljs.js +133 -0
  198. package/dist/platform-web/src/sqljs.js.map +1 -0
  199. package/dist/platform-web/src/worker.d.ts +79 -0
  200. package/dist/platform-web/src/worker.d.ts.map +1 -0
  201. package/dist/platform-web/src/worker.js +308 -0
  202. package/dist/platform-web/src/worker.js.map +1 -0
  203. package/dist/react/src/index.d.ts +59 -0
  204. package/dist/react/src/index.d.ts.map +1 -0
  205. package/dist/react/src/index.js +151 -0
  206. package/dist/react/src/index.js.map +1 -0
  207. package/dist/react.d.ts +2 -0
  208. package/dist/react.js +2 -0
  209. package/dist/schema/src/definition.d.ts +98 -0
  210. package/dist/schema/src/definition.d.ts.map +1 -0
  211. package/dist/schema/src/definition.js +84 -0
  212. package/dist/schema/src/definition.js.map +1 -0
  213. package/dist/schema/src/planner.d.ts +42 -0
  214. package/dist/schema/src/planner.d.ts.map +1 -0
  215. package/dist/schema/src/planner.js +131 -0
  216. package/dist/schema/src/planner.js.map +1 -0
  217. package/dist/schema/src/validators.d.ts +194 -0
  218. package/dist/schema/src/validators.d.ts.map +1 -0
  219. package/dist/schema/src/validators.js +158 -0
  220. package/dist/schema/src/validators.js.map +1 -0
  221. package/dist/svelte/src/index.d.ts +44 -0
  222. package/dist/svelte/src/index.d.ts.map +1 -0
  223. package/dist/svelte/src/index.js +75 -0
  224. package/dist/svelte/src/index.js.map +1 -0
  225. package/dist/svelte.d.ts +2 -0
  226. package/dist/svelte.js +2 -0
  227. package/package.json +152 -0
@@ -0,0 +1,98 @@
1
+ import { Infer, ObjectValidator, ObjectValidatorShape, Validator } from "./validators.js";
2
+
3
+ //#region ../schema/src/definition.d.ts
4
+ interface IndexDefinition {
5
+ name: string;
6
+ fields: string[];
7
+ }
8
+ interface SearchIndexDefinition {
9
+ name: string;
10
+ searchField: string;
11
+ filterFields: string[];
12
+ }
13
+ interface TableDefinitionOptions {
14
+ tableName?: string;
15
+ }
16
+ interface TableDocumentSystemFields {
17
+ _id: string;
18
+ _creationTime: number;
19
+ }
20
+ /**
21
+ * Describes a Syncore table and its indexes.
22
+ *
23
+ * Create tables with {@link defineTable} and then chain index helpers to make
24
+ * queries faster and more expressive.
25
+ */
26
+ declare class TableDefinition<TValidator extends Validator<unknown>> {
27
+ readonly validator: TValidator;
28
+ readonly indexes: IndexDefinition[];
29
+ readonly searchIndexes: SearchIndexDefinition[];
30
+ readonly options: TableDefinitionOptions;
31
+ constructor(validator: TValidator, options?: TableDefinitionOptions);
32
+ /**
33
+ * Add a named index for querying a table by one or more fields.
34
+ *
35
+ * @param name - The index name used from `ctx.db.query(...).withIndex(...)`.
36
+ * @param fields - The fields that participate in the index.
37
+ * @returns The same table definition for chaining.
38
+ */
39
+ index(name: string, fields: string[]): this;
40
+ /**
41
+ * Add a search index for text search.
42
+ *
43
+ * @param name - The search index name used from `withSearchIndex(...)`.
44
+ * @param config - The indexed search field and optional filter fields.
45
+ * @returns The same table definition for chaining.
46
+ */
47
+ searchIndex(name: string, config: {
48
+ searchField: string;
49
+ filterFields?: string[];
50
+ }): this;
51
+ }
52
+ type AnyTableDefinition = TableDefinition<Validator<unknown>>;
53
+ type InferDocument<TTable extends AnyTableDefinition> = Infer<TTable["validator"]> & TableDocumentSystemFields;
54
+ type InferTableInput<TTable extends AnyTableDefinition> = Omit<InferDocument<TTable>, keyof TableDocumentSystemFields>;
55
+ /**
56
+ * Define a table in a Syncore schema.
57
+ *
58
+ * Pass an object of validators describing the document fields stored in the
59
+ * table. Chain `.index(...)` or `.searchIndex(...)` to add query helpers.
60
+ *
61
+ * @example
62
+ * ```ts
63
+ * const tasks = defineTable({
64
+ * text: v.string(),
65
+ * done: v.boolean()
66
+ * }).index("by_done", ["done"]);
67
+ * ```
68
+ */
69
+ declare function defineTable<TShape extends ObjectValidatorShape>(validator: TShape): TableDefinition<ObjectValidator<TShape>>;
70
+ declare function defineTable<TValidator extends Validator<unknown>>(validator: TValidator): TableDefinition<TValidator>;
71
+ interface SyncoreSchemaDefinition {
72
+ [tableName: string]: AnyTableDefinition;
73
+ }
74
+ declare class SyncoreSchema<TTables extends SyncoreSchemaDefinition> {
75
+ readonly tables: TTables;
76
+ constructor(tables: TTables);
77
+ getTable<TTableName extends Extract<keyof TTables, string>>(tableName: TTableName): TTables[TTableName];
78
+ tableNames(): Array<Extract<keyof TTables, string>>;
79
+ }
80
+ /**
81
+ * Define the tables that make up your Syncore app.
82
+ *
83
+ * The returned schema is used by runtimes, code generation, and type inference.
84
+ *
85
+ * @example
86
+ * ```ts
87
+ * export default defineSchema({
88
+ * tasks: defineTable({
89
+ * text: v.string(),
90
+ * done: v.boolean()
91
+ * })
92
+ * });
93
+ * ```
94
+ */
95
+ declare function defineSchema<TTables extends SyncoreSchemaDefinition>(tables: TTables): SyncoreSchema<TTables>;
96
+ //#endregion
97
+ export { AnyTableDefinition, IndexDefinition, InferDocument, InferTableInput, SearchIndexDefinition, SyncoreSchema, SyncoreSchemaDefinition, TableDefinition, TableDefinitionOptions, TableDocumentSystemFields, defineSchema, defineTable };
98
+ //# sourceMappingURL=definition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definition.d.ts","names":[],"sources":["../../../../schema/src/definition.ts"],"mappings":";;;UAQiB,eAAA;EACf,IAAA;EACA,MAAA;AAAA;AAAA,UAGe,qBAAA;EACf,IAAA;EACA,WAAA;EACA,YAAA;AAAA;AAAA,UAGe,sBAAA;EACf,SAAA;AAAA;AAAA,UAGe,yBAAA;EACf,GAAA;EACA,aAAA;AAAA;;;;;AAFF;;cAWa,eAAA,oBAAmC,SAAA;EAAA,SAM5B,SAAA,EAAW,UAAA;EAAA,SALpB,OAAA,EAAS,eAAA;EAAA,SACT,aAAA,EAAe,qBAAA;EAAA,SACf,OAAA,EAAS,sBAAA;cAGA,SAAA,EAAW,UAAA,EAC3B,OAAA,GAAU,sBAAA;EAPkC;;;;;;;EAmB9C,KAAA,CAAM,IAAA,UAAc,MAAA;EAZc;;;;;;;EAwBlC,WAAA,CACE,IAAA,UACA,MAAA;IAAU,WAAA;IAAqB,YAAA;EAAA;AAAA;AAAA,KAWvB,kBAAA,GAAqB,eAAA,CAAgB,SAAA;AAAA,KAErC,aAAA,gBAA6B,kBAAA,IAAsB,KAAA,CAC7D,MAAA,iBAEA,yBAAA;AAAA,KAEU,eAAA,gBAA+B,kBAAA,IAAsB,IAAA,CAC/D,aAAA,CAAc,MAAA,SACR,yBAAA;;;;;;;;;;;;AATR;;;iBA0BgB,WAAA,gBAA2B,oBAAA,CAAA,CACzC,SAAA,EAAW,MAAA,GACV,eAAA,CAAgB,eAAA,CAAgB,MAAA;AAAA,iBACnB,WAAA,oBAA+B,SAAA,UAAA,CAC7C,SAAA,EAAW,UAAA,GACV,eAAA,CAAgB,UAAA;AAAA,UAOF,uBAAA;EAAA,CACd,SAAA,WAAoB,kBAAA;AAAA;AAAA,cAGV,aAAA,iBAA8B,uBAAA;EAAA,SACb,MAAA,EAAQ,OAAA;cAAR,MAAA,EAAQ,OAAA;EAEpC,QAAA,oBAA4B,OAAA,OAAc,OAAA,UAAA,CACxC,SAAA,EAAW,UAAA,GACV,OAAA,CAAQ,UAAA;EAQX,UAAA,CAAA,GAAc,KAAA,CAAM,OAAA,OAAc,OAAA;AAAA;;;;;;;;AAhDpC;;;;;;;;iBAoEgB,YAAA,iBAA6B,uBAAA,CAAA,CAC3C,MAAA,EAAQ,OAAA,GACP,aAAA,CAAc,OAAA"}
@@ -0,0 +1,84 @@
1
+ import { ensureObjectValidator } from "./validators.js";
2
+ //#region ../schema/src/definition.ts
3
+ /**
4
+ * Describes a Syncore table and its indexes.
5
+ *
6
+ * Create tables with {@link defineTable} and then chain index helpers to make
7
+ * queries faster and more expressive.
8
+ */
9
+ var TableDefinition = class {
10
+ indexes = [];
11
+ searchIndexes = [];
12
+ options;
13
+ constructor(validator, options) {
14
+ this.validator = validator;
15
+ this.options = options ?? {};
16
+ }
17
+ /**
18
+ * Add a named index for querying a table by one or more fields.
19
+ *
20
+ * @param name - The index name used from `ctx.db.query(...).withIndex(...)`.
21
+ * @param fields - The fields that participate in the index.
22
+ * @returns The same table definition for chaining.
23
+ */
24
+ index(name, fields) {
25
+ this.indexes.push({
26
+ name,
27
+ fields
28
+ });
29
+ return this;
30
+ }
31
+ /**
32
+ * Add a search index for text search.
33
+ *
34
+ * @param name - The search index name used from `withSearchIndex(...)`.
35
+ * @param config - The indexed search field and optional filter fields.
36
+ * @returns The same table definition for chaining.
37
+ */
38
+ searchIndex(name, config) {
39
+ this.searchIndexes.push({
40
+ name,
41
+ searchField: config.searchField,
42
+ filterFields: config.filterFields ?? []
43
+ });
44
+ return this;
45
+ }
46
+ };
47
+ function defineTable(validator) {
48
+ return new TableDefinition(ensureObjectValidator(validator));
49
+ }
50
+ var SyncoreSchema = class {
51
+ constructor(tables) {
52
+ this.tables = tables;
53
+ }
54
+ getTable(tableName) {
55
+ const table = this.tables[tableName];
56
+ if (!table) throw new Error(`Unknown table "${tableName}".`);
57
+ return table;
58
+ }
59
+ tableNames() {
60
+ return Object.keys(this.tables);
61
+ }
62
+ };
63
+ /**
64
+ * Define the tables that make up your Syncore app.
65
+ *
66
+ * The returned schema is used by runtimes, code generation, and type inference.
67
+ *
68
+ * @example
69
+ * ```ts
70
+ * export default defineSchema({
71
+ * tasks: defineTable({
72
+ * text: v.string(),
73
+ * done: v.boolean()
74
+ * })
75
+ * });
76
+ * ```
77
+ */
78
+ function defineSchema(tables) {
79
+ return new SyncoreSchema(tables);
80
+ }
81
+ //#endregion
82
+ export { SyncoreSchema, TableDefinition, defineSchema, defineTable };
83
+
84
+ //# sourceMappingURL=definition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definition.js","names":[],"sources":["../../../../schema/src/definition.ts"],"sourcesContent":["import {\r\n ensureObjectValidator,\r\n type Infer,\r\n type ObjectValidatorShape,\r\n type Validator\r\n} from \"./validators.js\";\r\nimport type { ObjectValidator } from \"./validators.js\";\r\n\r\nexport interface IndexDefinition {\r\n name: string;\r\n fields: string[];\r\n}\r\n\r\nexport interface SearchIndexDefinition {\r\n name: string;\r\n searchField: string;\r\n filterFields: string[];\r\n}\r\n\r\nexport interface TableDefinitionOptions {\r\n tableName?: string;\r\n}\r\n\r\nexport interface TableDocumentSystemFields {\r\n _id: string;\r\n _creationTime: number;\r\n}\r\n\r\n/**\r\n * Describes a Syncore table and its indexes.\r\n *\r\n * Create tables with {@link defineTable} and then chain index helpers to make\r\n * queries faster and more expressive.\r\n */\r\nexport class TableDefinition<TValidator extends Validator<unknown>> {\r\n readonly indexes: IndexDefinition[] = [];\r\n readonly searchIndexes: SearchIndexDefinition[] = [];\r\n readonly options: TableDefinitionOptions;\r\n\r\n constructor(\r\n public readonly validator: TValidator,\r\n options?: TableDefinitionOptions\r\n ) {\r\n this.options = options ?? {};\r\n }\r\n\r\n /**\r\n * Add a named index for querying a table by one or more fields.\r\n *\r\n * @param name - The index name used from `ctx.db.query(...).withIndex(...)`.\r\n * @param fields - The fields that participate in the index.\r\n * @returns The same table definition for chaining.\r\n */\r\n index(name: string, fields: string[]): this {\r\n this.indexes.push({ name, fields });\r\n return this;\r\n }\r\n\r\n /**\r\n * Add a search index for text search.\r\n *\r\n * @param name - The search index name used from `withSearchIndex(...)`.\r\n * @param config - The indexed search field and optional filter fields.\r\n * @returns The same table definition for chaining.\r\n */\r\n searchIndex(\r\n name: string,\r\n config: { searchField: string; filterFields?: string[] }\r\n ): this {\r\n this.searchIndexes.push({\r\n name,\r\n searchField: config.searchField,\r\n filterFields: config.filterFields ?? []\r\n });\r\n return this;\r\n }\r\n}\r\n\r\nexport type AnyTableDefinition = TableDefinition<Validator<unknown>>;\r\n\r\nexport type InferDocument<TTable extends AnyTableDefinition> = Infer<\r\n TTable[\"validator\"]\r\n> &\r\n TableDocumentSystemFields;\r\n\r\nexport type InferTableInput<TTable extends AnyTableDefinition> = Omit<\r\n InferDocument<TTable>,\r\n keyof TableDocumentSystemFields\r\n>;\r\n\r\n/**\r\n * Define a table in a Syncore schema.\r\n *\r\n * Pass an object of validators describing the document fields stored in the\r\n * table. Chain `.index(...)` or `.searchIndex(...)` to add query helpers.\r\n *\r\n * @example\r\n * ```ts\r\n * const tasks = defineTable({\r\n * text: v.string(),\r\n * done: v.boolean()\r\n * }).index(\"by_done\", [\"done\"]);\r\n * ```\r\n */\r\nexport function defineTable<TShape extends ObjectValidatorShape>(\r\n validator: TShape\r\n): TableDefinition<ObjectValidator<TShape>>;\r\nexport function defineTable<TValidator extends Validator<unknown>>(\r\n validator: TValidator\r\n): TableDefinition<TValidator>;\r\nexport function defineTable<TShape extends ObjectValidatorShape>(\r\n validator: TShape | Validator<unknown>\r\n): TableDefinition<Validator<unknown>> {\r\n return new TableDefinition(ensureObjectValidator(validator));\r\n}\r\n\r\nexport interface SyncoreSchemaDefinition {\r\n [tableName: string]: AnyTableDefinition;\r\n}\r\n\r\nexport class SyncoreSchema<TTables extends SyncoreSchemaDefinition> {\r\n constructor(public readonly tables: TTables) {}\r\n\r\n getTable<TTableName extends Extract<keyof TTables, string>>(\r\n tableName: TTableName\r\n ): TTables[TTableName] {\r\n const table = this.tables[tableName];\r\n if (!table) {\r\n throw new Error(`Unknown table \"${tableName}\".`);\r\n }\r\n return table;\r\n }\r\n\r\n tableNames(): Array<Extract<keyof TTables, string>> {\r\n return Object.keys(this.tables) as Array<Extract<keyof TTables, string>>;\r\n }\r\n}\r\n\r\n/**\r\n * Define the tables that make up your Syncore app.\r\n *\r\n * The returned schema is used by runtimes, code generation, and type inference.\r\n *\r\n * @example\r\n * ```ts\r\n * export default defineSchema({\r\n * tasks: defineTable({\r\n * text: v.string(),\r\n * done: v.boolean()\r\n * })\r\n * });\r\n * ```\r\n */\r\nexport function defineSchema<TTables extends SyncoreSchemaDefinition>(\r\n tables: TTables\r\n): SyncoreSchema<TTables> {\r\n return new SyncoreSchema(tables);\r\n}\r\n"],"mappings":";;;;;;;;AAkCA,IAAa,kBAAb,MAAoE;CAClE,UAAsC,EAAE;CACxC,gBAAkD,EAAE;CACpD;CAEA,YACE,WACA,SACA;AAFgB,OAAA,YAAA;AAGhB,OAAK,UAAU,WAAW,EAAE;;;;;;;;;CAU9B,MAAM,MAAc,QAAwB;AAC1C,OAAK,QAAQ,KAAK;GAAE;GAAM;GAAQ,CAAC;AACnC,SAAO;;;;;;;;;CAUT,YACE,MACA,QACM;AACN,OAAK,cAAc,KAAK;GACtB;GACA,aAAa,OAAO;GACpB,cAAc,OAAO,gBAAgB,EAAE;GACxC,CAAC;AACF,SAAO;;;AAoCX,SAAgB,YACd,WACqC;AACrC,QAAO,IAAI,gBAAgB,sBAAsB,UAAU,CAAC;;AAO9D,IAAa,gBAAb,MAAoE;CAClE,YAAY,QAAiC;AAAjB,OAAA,SAAA;;CAE5B,SACE,WACqB;EACrB,MAAM,QAAQ,KAAK,OAAO;AAC1B,MAAI,CAAC,MACH,OAAM,IAAI,MAAM,kBAAkB,UAAU,IAAI;AAElD,SAAO;;CAGT,aAAoD;AAClD,SAAO,OAAO,KAAK,KAAK,OAAO;;;;;;;;;;;;;;;;;;AAmBnC,SAAgB,aACd,QACwB;AACxB,QAAO,IAAI,cAAc,OAAO"}
@@ -0,0 +1,42 @@
1
+ import { ValidatorDescription } from "./validators.js";
2
+ import { SearchIndexDefinition, SyncoreSchema, SyncoreSchemaDefinition } from "./definition.js";
3
+
4
+ //#region ../schema/src/planner.d.ts
5
+ interface TableSnapshot {
6
+ name: string;
7
+ validator: ValidatorDescription;
8
+ indexes: Array<{
9
+ name: string;
10
+ fields: string[];
11
+ }>;
12
+ searchIndexes: Array<{
13
+ name: string;
14
+ searchField: string;
15
+ filterFields: string[];
16
+ }>;
17
+ }
18
+ interface SchemaSnapshot {
19
+ version: 1;
20
+ tables: TableSnapshot[];
21
+ hash: string;
22
+ }
23
+ interface SchemaMigrationPlan {
24
+ previousHash: string | null;
25
+ nextHash: string;
26
+ statements: string[];
27
+ warnings: string[];
28
+ destructiveChanges: string[];
29
+ }
30
+ declare function createSchemaSnapshot<TTables extends SyncoreSchemaDefinition>(schema: SyncoreSchema<TTables>): SchemaSnapshot;
31
+ declare function diffSchemaSnapshots(previousSnapshot: SchemaSnapshot | null | undefined, nextSnapshot: SchemaSnapshot): SchemaMigrationPlan;
32
+ declare function renderMigrationSql(plan: SchemaMigrationPlan, options?: {
33
+ title?: string;
34
+ }): string;
35
+ declare function parseSchemaSnapshot(source: string): SchemaSnapshot;
36
+ declare function renderCreateTableStatement(tableName: string): string;
37
+ declare function renderCreateIndexStatement(tableName: string, indexName: string, fields: string[]): string;
38
+ declare function renderCreateSearchIndexStatement(tableName: string, searchIndex: SearchIndexDefinition | TableSnapshot["searchIndexes"][number]): string;
39
+ declare function searchIndexTableName(tableName: string, indexName: string): string;
40
+ //#endregion
41
+ export { SchemaMigrationPlan, SchemaSnapshot, TableSnapshot, createSchemaSnapshot, diffSchemaSnapshots, parseSchemaSnapshot, renderCreateIndexStatement, renderCreateSearchIndexStatement, renderCreateTableStatement, renderMigrationSql, searchIndexTableName };
42
+ //# sourceMappingURL=planner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"planner.d.ts","names":[],"sources":["../../../../schema/src/planner.ts"],"mappings":";;;;UAUiB,aAAA;EACf,IAAA;EACA,SAAA,EAAW,oBAAA;EACX,OAAA,EAAS,KAAA;IACP,IAAA;IACA,MAAA;EAAA;EAEF,aAAA,EAAe,KAAA;IACb,IAAA;IACA,WAAA;IACA,YAAA;EAAA;AAAA;AAAA,UAIa,cAAA;EACf,OAAA;EACA,MAAA,EAAQ,aAAA;EACR,IAAA;AAAA;AAAA,UAGe,mBAAA;EACf,YAAA;EACA,QAAA;EACA,UAAA;EACA,QAAA;EACA,kBAAA;AAAA;AAAA,iBAGc,oBAAA,iBAAqC,uBAAA,CAAA,CACnD,MAAA,EAAQ,aAAA,CAAc,OAAA,IACrB,cAAA;AAAA,iBAoCa,mBAAA,CACd,gBAAA,EAAkB,cAAA,qBAClB,YAAA,EAAc,cAAA,GACb,mBAAA;AAAA,iBAqGa,kBAAA,CACd,IAAA,EAAM,mBAAA,EACN,OAAA;EAAY,KAAA;AAAA;AAAA,iBA+BE,mBAAA,CAAoB,MAAA,WAAiB,cAAA;AAAA,iBAQrC,0BAAA,CAA2B,SAAA;AAAA,iBAS3B,0BAAA,CACd,SAAA,UACA,SAAA,UACA,MAAA;AAAA,iBAUc,gCAAA,CACd,SAAA,UACA,WAAA,EAAa,qBAAA,GAAwB,aAAA;AAAA,iBAOvB,oBAAA,CAAqB,SAAA,UAAmB,SAAA"}
@@ -0,0 +1,131 @@
1
+ import { describeValidator } from "./validators.js";
2
+ //#region ../schema/src/planner.ts
3
+ function createSchemaSnapshot(schema) {
4
+ const base = {
5
+ version: 1,
6
+ tables: schema.tableNames().sort((left, right) => left.localeCompare(right)).map((tableName) => {
7
+ const table = schema.getTable(tableName);
8
+ return {
9
+ name: tableName,
10
+ validator: describeValidator(table.validator),
11
+ indexes: table.indexes.map((index) => ({
12
+ name: index.name,
13
+ fields: [...index.fields]
14
+ })).sort((left, right) => left.name.localeCompare(right.name)),
15
+ searchIndexes: table.searchIndexes.map((index) => ({
16
+ name: index.name,
17
+ searchField: index.searchField,
18
+ filterFields: [...index.filterFields]
19
+ })).sort((left, right) => left.name.localeCompare(right.name))
20
+ };
21
+ })
22
+ };
23
+ return {
24
+ ...base,
25
+ hash: createSchemaHash(base)
26
+ };
27
+ }
28
+ function diffSchemaSnapshots(previousSnapshot, nextSnapshot) {
29
+ const statements = [];
30
+ const warnings = [];
31
+ const destructiveChanges = [];
32
+ const previousTables = new Map((previousSnapshot?.tables ?? []).map((table) => [table.name, table]));
33
+ const nextTables = new Map(nextSnapshot.tables.map((table) => [table.name, table]));
34
+ for (const table of nextSnapshot.tables) {
35
+ const previousTable = previousTables.get(table.name);
36
+ if (!previousTable) {
37
+ statements.push(renderCreateTableStatement(table.name));
38
+ for (const index of table.indexes) statements.push(renderCreateIndexStatement(table.name, index.name, index.fields));
39
+ for (const searchIndex of table.searchIndexes) statements.push(renderCreateSearchIndexStatement(table.name, searchIndex));
40
+ continue;
41
+ }
42
+ if (stableStringify(previousTable.validator) !== stableStringify(table.validator)) warnings.push(`Validator changed for table "${table.name}". Existing rows are not rewritten automatically.`);
43
+ const previousIndexes = new Map(previousTable.indexes.map((index) => [index.name, index]));
44
+ const nextIndexes = new Map(table.indexes.map((index) => [index.name, index]));
45
+ for (const index of table.indexes) {
46
+ const previousIndex = previousIndexes.get(index.name);
47
+ if (!previousIndex) {
48
+ statements.push(renderCreateIndexStatement(table.name, index.name, index.fields));
49
+ continue;
50
+ }
51
+ if (stableStringify(previousIndex.fields) !== stableStringify(index.fields)) destructiveChanges.push(`Index "${table.name}.${index.name}" changed fields and requires a manual migration.`);
52
+ }
53
+ for (const previousIndex of previousTable.indexes) if (!nextIndexes.has(previousIndex.name)) destructiveChanges.push(`Index "${table.name}.${previousIndex.name}" was removed and requires a manual migration.`);
54
+ const previousSearchIndexes = new Map(previousTable.searchIndexes.map((index) => [index.name, index]));
55
+ const nextSearchIndexes = new Map(table.searchIndexes.map((index) => [index.name, index]));
56
+ for (const searchIndex of table.searchIndexes) {
57
+ const previousSearchIndex = previousSearchIndexes.get(searchIndex.name);
58
+ if (!previousSearchIndex) {
59
+ statements.push(renderCreateSearchIndexStatement(table.name, searchIndex));
60
+ continue;
61
+ }
62
+ if (stableStringify(previousSearchIndex) !== stableStringify(searchIndex)) destructiveChanges.push(`Search index "${table.name}.${searchIndex.name}" changed and requires a manual migration.`);
63
+ }
64
+ for (const previousSearchIndex of previousTable.searchIndexes) if (!nextSearchIndexes.has(previousSearchIndex.name)) destructiveChanges.push(`Search index "${table.name}.${previousSearchIndex.name}" was removed and requires a manual migration.`);
65
+ }
66
+ for (const previousTable of previousSnapshot?.tables ?? []) if (!nextTables.has(previousTable.name)) destructiveChanges.push(`Table "${previousTable.name}" was removed and requires a manual migration.`);
67
+ return {
68
+ previousHash: previousSnapshot?.hash ?? null,
69
+ nextHash: nextSnapshot.hash,
70
+ statements,
71
+ warnings,
72
+ destructiveChanges
73
+ };
74
+ }
75
+ function renderMigrationSql(plan, options) {
76
+ const lines = [];
77
+ lines.push(`-- ${options?.title ?? "Syncore migration"}`);
78
+ lines.push(`-- previous: ${plan.previousHash ?? "none"}`);
79
+ lines.push(`-- next: ${plan.nextHash}`);
80
+ for (const warning of plan.warnings) lines.push(`-- warning: ${warning}`);
81
+ if (plan.destructiveChanges.length > 0) for (const destructiveChange of plan.destructiveChanges) lines.push(`-- destructive: ${destructiveChange}`);
82
+ if (plan.statements.length > 0) {
83
+ lines.push("");
84
+ for (const statement of plan.statements) lines.push(statement);
85
+ } else {
86
+ lines.push("");
87
+ lines.push("-- no-op");
88
+ }
89
+ return `${lines.join("\n")}\n`;
90
+ }
91
+ function parseSchemaSnapshot(source) {
92
+ const parsed = JSON.parse(source);
93
+ if (parsed.version !== 1 || !Array.isArray(parsed.tables) || typeof parsed.hash !== "string") throw new Error("Invalid schema snapshot file.");
94
+ return parsed;
95
+ }
96
+ function renderCreateTableStatement(tableName) {
97
+ return `
98
+ CREATE TABLE IF NOT EXISTS ${quoteIdentifier(tableName)} (
99
+ _id TEXT PRIMARY KEY,
100
+ _creationTime INTEGER NOT NULL,
101
+ _json TEXT NOT NULL
102
+ );`.trim();
103
+ }
104
+ function renderCreateIndexStatement(tableName, indexName, fields) {
105
+ const expressions = fields.map((field) => `json_extract(_json, '$.${field}')`).join(", ");
106
+ return `CREATE INDEX IF NOT EXISTS ${quoteIdentifier(`idx_${tableName}_${indexName}`)} ON ${quoteIdentifier(tableName)} (${expressions});`;
107
+ }
108
+ function renderCreateSearchIndexStatement(tableName, searchIndex) {
109
+ return `CREATE VIRTUAL TABLE IF NOT EXISTS ${quoteIdentifier(searchIndexTableName(tableName, searchIndex.name))} USING fts5(_id UNINDEXED, search_value);`;
110
+ }
111
+ function searchIndexTableName(tableName, indexName) {
112
+ return `fts_${tableName}_${indexName}`;
113
+ }
114
+ function createSchemaHash(value) {
115
+ return stableStringify(value);
116
+ }
117
+ function quoteIdentifier(identifier) {
118
+ return `"${identifier.replaceAll("\"", "\"\"")}"`;
119
+ }
120
+ function stableStringify(value) {
121
+ return JSON.stringify(sortValue(value));
122
+ }
123
+ function sortValue(value) {
124
+ if (Array.isArray(value)) return value.map(sortValue);
125
+ if (value && typeof value === "object") return Object.fromEntries(Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, nested]) => [key, sortValue(nested)]));
126
+ return value;
127
+ }
128
+ //#endregion
129
+ export { createSchemaSnapshot, diffSchemaSnapshots, parseSchemaSnapshot, renderCreateIndexStatement, renderCreateSearchIndexStatement, renderCreateTableStatement, renderMigrationSql, searchIndexTableName };
130
+
131
+ //# sourceMappingURL=planner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"planner.js","names":[],"sources":["../../../../schema/src/planner.ts"],"sourcesContent":["import {\r\n type SearchIndexDefinition,\r\n type SyncoreSchemaDefinition,\r\n type SyncoreSchema\r\n} from \"./definition.js\";\r\nimport {\r\n describeValidator,\r\n type ValidatorDescription\r\n} from \"./validators.js\";\r\n\r\nexport interface TableSnapshot {\r\n name: string;\r\n validator: ValidatorDescription;\r\n indexes: Array<{\r\n name: string;\r\n fields: string[];\r\n }>;\r\n searchIndexes: Array<{\r\n name: string;\r\n searchField: string;\r\n filterFields: string[];\r\n }>;\r\n}\r\n\r\nexport interface SchemaSnapshot {\r\n version: 1;\r\n tables: TableSnapshot[];\r\n hash: string;\r\n}\r\n\r\nexport interface SchemaMigrationPlan {\r\n previousHash: string | null;\r\n nextHash: string;\r\n statements: string[];\r\n warnings: string[];\r\n destructiveChanges: string[];\r\n}\r\n\r\nexport function createSchemaSnapshot<TTables extends SyncoreSchemaDefinition>(\r\n schema: SyncoreSchema<TTables>\r\n): SchemaSnapshot {\r\n const tables = schema\r\n .tableNames()\r\n .sort((left, right) => left.localeCompare(right))\r\n .map((tableName) => {\r\n const table = schema.getTable(tableName);\r\n return {\r\n name: tableName,\r\n validator: describeValidator(table.validator),\r\n indexes: table.indexes\r\n .map((index) => ({\r\n name: index.name,\r\n fields: [...index.fields]\r\n }))\r\n .sort((left, right) => left.name.localeCompare(right.name)),\r\n searchIndexes: table.searchIndexes\r\n .map((index) => ({\r\n name: index.name,\r\n searchField: index.searchField,\r\n filterFields: [...index.filterFields]\r\n }))\r\n .sort((left, right) => left.name.localeCompare(right.name))\r\n };\r\n });\r\n\r\n const base = {\r\n version: 1 as const,\r\n tables\r\n };\r\n\r\n return {\r\n ...base,\r\n hash: createSchemaHash(base)\r\n };\r\n}\r\n\r\nexport function diffSchemaSnapshots(\r\n previousSnapshot: SchemaSnapshot | null | undefined,\r\n nextSnapshot: SchemaSnapshot\r\n): SchemaMigrationPlan {\r\n const statements: string[] = [];\r\n const warnings: string[] = [];\r\n const destructiveChanges: string[] = [];\r\n\r\n const previousTables = new Map(\r\n (previousSnapshot?.tables ?? []).map((table) => [table.name, table])\r\n );\r\n const nextTables = new Map(nextSnapshot.tables.map((table) => [table.name, table]));\r\n\r\n for (const table of nextSnapshot.tables) {\r\n const previousTable = previousTables.get(table.name);\r\n if (!previousTable) {\r\n statements.push(renderCreateTableStatement(table.name));\r\n for (const index of table.indexes) {\r\n statements.push(renderCreateIndexStatement(table.name, index.name, index.fields));\r\n }\r\n for (const searchIndex of table.searchIndexes) {\r\n statements.push(renderCreateSearchIndexStatement(table.name, searchIndex));\r\n }\r\n continue;\r\n }\r\n\r\n if (stableStringify(previousTable.validator) !== stableStringify(table.validator)) {\r\n warnings.push(\r\n `Validator changed for table \"${table.name}\". Existing rows are not rewritten automatically.`\r\n );\r\n }\r\n\r\n const previousIndexes = new Map(\r\n previousTable.indexes.map((index) => [index.name, index])\r\n );\r\n const nextIndexes = new Map(table.indexes.map((index) => [index.name, index]));\r\n\r\n for (const index of table.indexes) {\r\n const previousIndex = previousIndexes.get(index.name);\r\n if (!previousIndex) {\r\n statements.push(renderCreateIndexStatement(table.name, index.name, index.fields));\r\n continue;\r\n }\r\n if (stableStringify(previousIndex.fields) !== stableStringify(index.fields)) {\r\n destructiveChanges.push(\r\n `Index \"${table.name}.${index.name}\" changed fields and requires a manual migration.`\r\n );\r\n }\r\n }\r\n\r\n for (const previousIndex of previousTable.indexes) {\r\n if (!nextIndexes.has(previousIndex.name)) {\r\n destructiveChanges.push(\r\n `Index \"${table.name}.${previousIndex.name}\" was removed and requires a manual migration.`\r\n );\r\n }\r\n }\r\n\r\n const previousSearchIndexes = new Map(\r\n previousTable.searchIndexes.map((index) => [index.name, index])\r\n );\r\n const nextSearchIndexes = new Map(\r\n table.searchIndexes.map((index) => [index.name, index])\r\n );\r\n\r\n for (const searchIndex of table.searchIndexes) {\r\n const previousSearchIndex = previousSearchIndexes.get(searchIndex.name);\r\n if (!previousSearchIndex) {\r\n statements.push(renderCreateSearchIndexStatement(table.name, searchIndex));\r\n continue;\r\n }\r\n if (stableStringify(previousSearchIndex) !== stableStringify(searchIndex)) {\r\n destructiveChanges.push(\r\n `Search index \"${table.name}.${searchIndex.name}\" changed and requires a manual migration.`\r\n );\r\n }\r\n }\r\n\r\n for (const previousSearchIndex of previousTable.searchIndexes) {\r\n if (!nextSearchIndexes.has(previousSearchIndex.name)) {\r\n destructiveChanges.push(\r\n `Search index \"${table.name}.${previousSearchIndex.name}\" was removed and requires a manual migration.`\r\n );\r\n }\r\n }\r\n }\r\n\r\n for (const previousTable of previousSnapshot?.tables ?? []) {\r\n if (!nextTables.has(previousTable.name)) {\r\n destructiveChanges.push(\r\n `Table \"${previousTable.name}\" was removed and requires a manual migration.`\r\n );\r\n }\r\n }\r\n\r\n return {\r\n previousHash: previousSnapshot?.hash ?? null,\r\n nextHash: nextSnapshot.hash,\r\n statements,\r\n warnings,\r\n destructiveChanges\r\n };\r\n}\r\n\r\nexport function renderMigrationSql(\r\n plan: SchemaMigrationPlan,\r\n options?: { title?: string }\r\n): string {\r\n const lines: string[] = [];\r\n\r\n lines.push(`-- ${options?.title ?? \"Syncore migration\"}`);\r\n lines.push(`-- previous: ${plan.previousHash ?? \"none\"}`);\r\n lines.push(`-- next: ${plan.nextHash}`);\r\n\r\n for (const warning of plan.warnings) {\r\n lines.push(`-- warning: ${warning}`);\r\n }\r\n\r\n if (plan.destructiveChanges.length > 0) {\r\n for (const destructiveChange of plan.destructiveChanges) {\r\n lines.push(`-- destructive: ${destructiveChange}`);\r\n }\r\n }\r\n\r\n if (plan.statements.length > 0) {\r\n lines.push(\"\");\r\n for (const statement of plan.statements) {\r\n lines.push(statement);\r\n }\r\n } else {\r\n lines.push(\"\");\r\n lines.push(\"-- no-op\");\r\n }\r\n\r\n return `${lines.join(\"\\n\")}\\n`;\r\n}\r\n\r\nexport function parseSchemaSnapshot(source: string): SchemaSnapshot {\r\n const parsed = JSON.parse(source) as SchemaSnapshot;\r\n if (parsed.version !== 1 || !Array.isArray(parsed.tables) || typeof parsed.hash !== \"string\") {\r\n throw new Error(\"Invalid schema snapshot file.\");\r\n }\r\n return parsed;\r\n}\r\n\r\nexport function renderCreateTableStatement(tableName: string): string {\r\n return `\r\nCREATE TABLE IF NOT EXISTS ${quoteIdentifier(tableName)} (\r\n _id TEXT PRIMARY KEY,\r\n _creationTime INTEGER NOT NULL,\r\n _json TEXT NOT NULL\r\n);`.trim();\r\n}\r\n\r\nexport function renderCreateIndexStatement(\r\n tableName: string,\r\n indexName: string,\r\n fields: string[]\r\n): string {\r\n const expressions = fields\r\n .map((field) => `json_extract(_json, '$.${field}')`)\r\n .join(\", \");\r\n return `CREATE INDEX IF NOT EXISTS ${quoteIdentifier(\r\n `idx_${tableName}_${indexName}`\r\n )} ON ${quoteIdentifier(tableName)} (${expressions});`;\r\n}\r\n\r\nexport function renderCreateSearchIndexStatement(\r\n tableName: string,\r\n searchIndex: SearchIndexDefinition | TableSnapshot[\"searchIndexes\"][number]\r\n): string {\r\n return `CREATE VIRTUAL TABLE IF NOT EXISTS ${quoteIdentifier(\r\n searchIndexTableName(tableName, searchIndex.name)\r\n )} USING fts5(_id UNINDEXED, search_value);`;\r\n}\r\n\r\nexport function searchIndexTableName(tableName: string, indexName: string): string {\r\n return `fts_${tableName}_${indexName}`;\r\n}\r\n\r\nfunction createSchemaHash(value: Omit<SchemaSnapshot, \"hash\">): string {\r\n return stableStringify(value);\r\n}\r\n\r\nfunction quoteIdentifier(identifier: string): string {\r\n return `\"${identifier.replaceAll('\"', '\"\"')}\"`;\r\n}\r\n\r\nfunction stableStringify(value: unknown): string {\r\n return JSON.stringify(sortValue(value));\r\n}\r\n\r\nfunction sortValue(value: unknown): unknown {\r\n if (Array.isArray(value)) {\r\n return value.map(sortValue);\r\n }\r\n if (value && typeof value === \"object\") {\r\n return Object.fromEntries(\r\n Object.entries(value as Record<string, unknown>)\r\n .sort(([left], [right]) => left.localeCompare(right))\r\n .map(([key, nested]) => [key, sortValue(nested)])\r\n );\r\n }\r\n return value;\r\n}\r\n"],"mappings":"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"}
@@ -0,0 +1,194 @@
1
+ //#region ../schema/src/validators.d.ts
2
+ type ValidatorKind = "string" | "number" | "boolean" | "literal" | "array" | "object" | "id" | "optional" | "any" | "null";
3
+ /**
4
+ * Validates unknown input at runtime and carries its parsed TypeScript type.
5
+ *
6
+ * Syncore uses validators for function arguments, return values, and table
7
+ * definitions. Most apps create validators through {@link v} instead of
8
+ * instantiating validator classes directly.
9
+ */
10
+ interface Validator<TValue> {
11
+ readonly kind: ValidatorKind;
12
+ /**
13
+ * Parse and validate an unknown value.
14
+ *
15
+ * @param value - The value to validate.
16
+ * @param path - A human-readable path used in validation errors.
17
+ * @returns The parsed value when validation succeeds.
18
+ */
19
+ parse(value: unknown, path?: string): TValue;
20
+ }
21
+ type ValidatorDescription = {
22
+ kind: "string";
23
+ } | {
24
+ kind: "number";
25
+ } | {
26
+ kind: "boolean";
27
+ } | {
28
+ kind: "null";
29
+ } | {
30
+ kind: "any";
31
+ } | {
32
+ kind: "literal";
33
+ value: string | number | boolean | null;
34
+ } | {
35
+ kind: "array";
36
+ item: ValidatorDescription;
37
+ } | {
38
+ kind: "object";
39
+ shape: Record<string, ValidatorDescription>;
40
+ } | {
41
+ kind: "id";
42
+ tableName: string;
43
+ } | {
44
+ kind: "optional";
45
+ inner: ValidatorDescription;
46
+ };
47
+ interface ObjectValidatorShape {
48
+ [key: string]: Validator<unknown>;
49
+ }
50
+ declare class StringValidator implements Validator<string> {
51
+ readonly kind: "string";
52
+ parse(value: unknown, path?: string): string;
53
+ }
54
+ declare class NumberValidator implements Validator<number> {
55
+ readonly kind: "number";
56
+ parse(value: unknown, path?: string): number;
57
+ }
58
+ declare class BooleanValidator implements Validator<boolean> {
59
+ readonly kind: "boolean";
60
+ parse(value: unknown, path?: string): boolean;
61
+ }
62
+ declare class NullValidator implements Validator<null> {
63
+ readonly kind: "null";
64
+ parse(value: unknown, path?: string): null;
65
+ }
66
+ declare class AnyValidator implements Validator<unknown> {
67
+ readonly kind: "any";
68
+ parse(value: unknown): unknown;
69
+ }
70
+ declare class LiteralValidator<TValue extends string | number | boolean | null> implements Validator<TValue> {
71
+ readonly literalValue: TValue;
72
+ readonly kind: "literal";
73
+ constructor(literalValue: TValue);
74
+ parse(value: unknown, path?: string): TValue;
75
+ }
76
+ declare class ArrayValidator<TItem> implements Validator<TItem[]> {
77
+ readonly itemValidator: Validator<TItem>;
78
+ readonly kind: "array";
79
+ constructor(itemValidator: Validator<TItem>);
80
+ parse(value: unknown, path?: string): TItem[];
81
+ }
82
+ declare class ObjectValidator<TShape extends ObjectValidatorShape> implements Validator<{ [TKey in keyof TShape]: Infer<TShape[TKey]> }> {
83
+ readonly shape: TShape;
84
+ readonly kind: "object";
85
+ constructor(shape: TShape);
86
+ parse(value: unknown, path?: string): { [TKey in keyof TShape]: Infer<TShape[TKey]> };
87
+ }
88
+ declare class IdValidator<TTableName extends string> implements Validator<string> {
89
+ readonly tableName: TTableName;
90
+ readonly kind: "id";
91
+ constructor(tableName: TTableName);
92
+ parse(value: unknown, path?: string): string;
93
+ }
94
+ declare class OptionalValidator<TValue> implements Validator<TValue | undefined> {
95
+ readonly inner: Validator<TValue>;
96
+ readonly kind: "optional";
97
+ constructor(inner: Validator<TValue>);
98
+ parse(value: unknown, path?: string): TValue | undefined;
99
+ }
100
+ type Infer<TValidator> = TValidator extends Validator<infer TValue> ? TValue : never;
101
+ type ValidatorMap = Record<string, Validator<unknown>>;
102
+ /**
103
+ * The public validator builder API.
104
+ *
105
+ * Hover each property in your editor to see what it validates and how to use it.
106
+ */
107
+ interface ValidatorBuilderApi {
108
+ /**
109
+ * Validate a string value.
110
+ *
111
+ * @returns A validator that accepts JavaScript strings.
112
+ */
113
+ string(): StringValidator;
114
+ /**
115
+ * Validate a number value.
116
+ *
117
+ * @returns A validator that accepts finite JavaScript numbers.
118
+ */
119
+ number(): NumberValidator;
120
+ /**
121
+ * Validate a boolean value.
122
+ *
123
+ * @returns A validator that accepts `true` and `false`.
124
+ */
125
+ boolean(): BooleanValidator;
126
+ /**
127
+ * Validate the literal value `null`.
128
+ *
129
+ * @returns A validator that only accepts `null`.
130
+ */
131
+ null(): NullValidator;
132
+ /**
133
+ * Accept any value without validation.
134
+ *
135
+ * Use this sparingly for escape hatches when you do not want Syncore to
136
+ * enforce a more specific runtime shape.
137
+ */
138
+ any(): AnyValidator;
139
+ /**
140
+ * Validate a single literal value.
141
+ *
142
+ * @param literalValue - The exact value that must be provided.
143
+ * @returns A validator that only accepts that one value.
144
+ */
145
+ literal<TValue extends string | number | boolean | null>(literalValue: TValue): LiteralValidator<TValue>;
146
+ /**
147
+ * Validate an array whose items all use the same validator.
148
+ *
149
+ * @param itemValidator - The validator for each item in the array.
150
+ * @returns A validator for arrays of the provided item type.
151
+ */
152
+ array<TItem>(itemValidator: Validator<TItem>): ArrayValidator<TItem>;
153
+ /**
154
+ * Validate an object with a fixed property shape.
155
+ *
156
+ * @param shape - The validators for each property on the object.
157
+ * @returns A validator for objects matching that shape.
158
+ */
159
+ object<TShape extends ObjectValidatorShape>(shape: TShape): ObjectValidator<TShape>;
160
+ /**
161
+ * Validate an identifier string that points at a table.
162
+ *
163
+ * Use this for document ids that come from Syncore tables.
164
+ *
165
+ * @param tableName - The name of the referenced table.
166
+ * @returns A validator for ids belonging to that table.
167
+ */
168
+ id<TTableName extends string>(tableName: TTableName): IdValidator<TTableName>;
169
+ /**
170
+ * Make another validator optional.
171
+ *
172
+ * @param inner - The validator for the defined case.
173
+ * @returns A validator that accepts `undefined` or the inner value.
174
+ */
175
+ optional<TValue>(inner: Validator<TValue>): OptionalValidator<TValue>;
176
+ }
177
+ declare function ensureObjectValidator(value: Validator<unknown> | ValidatorMap): Validator<unknown>;
178
+ /**
179
+ * Build runtime validators for schemas, function args, and return values.
180
+ *
181
+ * @example
182
+ * ```ts
183
+ * defineTable({
184
+ * text: v.string(),
185
+ * done: v.boolean(),
186
+ * ownerId: v.optional(v.id("users"))
187
+ * });
188
+ * ```
189
+ */
190
+ declare const v: ValidatorBuilderApi;
191
+ declare function describeValidator(validator: Validator<unknown>): ValidatorDescription;
192
+ //#endregion
193
+ export { AnyValidator, ArrayValidator, BooleanValidator, IdValidator, Infer, LiteralValidator, NullValidator, NumberValidator, ObjectValidator, ObjectValidatorShape, OptionalValidator, StringValidator, Validator, ValidatorBuilderApi, ValidatorDescription, ValidatorKind, ValidatorMap, describeValidator, ensureObjectValidator, v };
194
+ //# sourceMappingURL=validators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validators.d.ts","names":[],"sources":["../../../../schema/src/validators.ts"],"mappings":"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"}