solid-objects 0.13.2 → 0.14.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 (146) hide show
  1. package/CHANGELOG.md +126 -0
  2. package/README.md +188 -68
  3. package/dist/actor.d.ts +1 -0
  4. package/dist/actor.d.ts.map +1 -1
  5. package/dist/actor.js +9 -0
  6. package/dist/actor.js.map +1 -1
  7. package/dist/broadcast-worker.d.ts +1 -1
  8. package/dist/broadcast-worker.d.ts.map +1 -1
  9. package/dist/broadcast-worker.js +1 -1
  10. package/dist/broadcast-worker.js.map +1 -1
  11. package/dist/broken-pipe.d.ts +5 -0
  12. package/dist/broken-pipe.d.ts.map +1 -0
  13. package/dist/broken-pipe.js +8 -0
  14. package/dist/broken-pipe.js.map +1 -0
  15. package/dist/browser/host.d.ts +8 -0
  16. package/dist/browser/host.d.ts.map +1 -0
  17. package/dist/browser/host.js +22 -0
  18. package/dist/browser/host.js.map +1 -0
  19. package/dist/browser/tab-host.d.ts +43 -0
  20. package/dist/browser/tab-host.d.ts.map +1 -0
  21. package/dist/browser/tab-host.js +196 -0
  22. package/dist/browser/tab-host.js.map +1 -0
  23. package/dist/cli.d.ts +1 -0
  24. package/dist/cli.d.ts.map +1 -1
  25. package/dist/cli.js +6 -3
  26. package/dist/cli.js.map +1 -1
  27. package/dist/context.js +2 -2
  28. package/dist/context.js.map +1 -1
  29. package/dist/database/deadline.js +2 -2
  30. package/dist/database/deadline.js.map +1 -1
  31. package/dist/database/mysql.d.ts +1 -0
  32. package/dist/database/mysql.d.ts.map +1 -1
  33. package/dist/database/mysql.js +1 -0
  34. package/dist/database/mysql.js.map +1 -1
  35. package/dist/database/postgresql.d.ts +1 -0
  36. package/dist/database/postgresql.d.ts.map +1 -1
  37. package/dist/database/postgresql.js +1 -0
  38. package/dist/database/postgresql.js.map +1 -1
  39. package/dist/database/shared-sqlite-wasm.d.ts +74 -0
  40. package/dist/database/shared-sqlite-wasm.d.ts.map +1 -0
  41. package/dist/database/shared-sqlite-wasm.js +542 -0
  42. package/dist/database/shared-sqlite-wasm.js.map +1 -0
  43. package/dist/database/sqlite-wasm.d.ts +30 -0
  44. package/dist/database/sqlite-wasm.d.ts.map +1 -0
  45. package/dist/database/sqlite-wasm.js +185 -0
  46. package/dist/database/sqlite-wasm.js.map +1 -0
  47. package/dist/database/sqlite.d.ts +1 -0
  48. package/dist/database/sqlite.d.ts.map +1 -1
  49. package/dist/database/sqlite.js +1 -0
  50. package/dist/database/sqlite.js.map +1 -1
  51. package/dist/database/transaction-context.js +2 -2
  52. package/dist/database/transaction-context.js.map +1 -1
  53. package/dist/doctor.js +1 -1
  54. package/dist/doctor.js.map +1 -1
  55. package/dist/effect-worker.d.ts +1 -1
  56. package/dist/effect-worker.d.ts.map +1 -1
  57. package/dist/effect-worker.js +1 -1
  58. package/dist/effect-worker.js.map +1 -1
  59. package/dist/examples/quickstart-report.js +127 -0
  60. package/dist/examples/quickstart-report.js.map +1 -0
  61. package/dist/examples/sqlite-quickstart.js +59 -7
  62. package/dist/examples/sqlite-quickstart.js.map +1 -1
  63. package/dist/executable.js +4 -0
  64. package/dist/executable.js.map +1 -1
  65. package/dist/index.d.ts +3 -1
  66. package/dist/index.d.ts.map +1 -1
  67. package/dist/index.js +3 -1
  68. package/dist/index.js.map +1 -1
  69. package/dist/platform/context-store.d.ts +11 -0
  70. package/dist/platform/context-store.d.ts.map +1 -0
  71. package/dist/platform/context-store.js +28 -0
  72. package/dist/platform/context-store.js.map +1 -0
  73. package/dist/platform/host-identity.d.ts +11 -0
  74. package/dist/platform/host-identity.d.ts.map +1 -0
  75. package/dist/platform/host-identity.js +17 -0
  76. package/dist/platform/host-identity.js.map +1 -0
  77. package/dist/platform/node.d.ts +2 -0
  78. package/dist/platform/node.d.ts.map +1 -0
  79. package/dist/platform/node.js +11 -0
  80. package/dist/platform/node.js.map +1 -0
  81. package/dist/platform/turn-context-store.d.ts +7 -0
  82. package/dist/platform/turn-context-store.d.ts.map +1 -0
  83. package/dist/platform/turn-context-store.js +17 -0
  84. package/dist/platform/turn-context-store.js.map +1 -0
  85. package/dist/platform/uuid.d.ts +2 -0
  86. package/dist/platform/uuid.d.ts.map +1 -0
  87. package/dist/platform/uuid.js +4 -0
  88. package/dist/platform/uuid.js.map +1 -0
  89. package/dist/platform/web-locks.d.ts +2 -0
  90. package/dist/platform/web-locks.d.ts.map +1 -0
  91. package/dist/platform/web-locks.js +8 -0
  92. package/dist/platform/web-locks.js.map +1 -0
  93. package/dist/reminder-scheduler.d.ts +1 -1
  94. package/dist/reminder-scheduler.d.ts.map +1 -1
  95. package/dist/reminder-scheduler.js +1 -1
  96. package/dist/reminder-scheduler.js.map +1 -1
  97. package/dist/repository.d.ts.map +1 -1
  98. package/dist/repository.js +13 -6
  99. package/dist/repository.js.map +1 -1
  100. package/dist/runtime.d.ts +25 -1
  101. package/dist/runtime.d.ts.map +1 -1
  102. package/dist/runtime.js +62 -1
  103. package/dist/runtime.js.map +1 -1
  104. package/dist/serialization.d.ts.map +1 -1
  105. package/dist/serialization.js +2 -1
  106. package/dist/serialization.js.map +1 -1
  107. package/dist/transmit-effect.d.ts +2 -0
  108. package/dist/transmit-effect.d.ts.map +1 -0
  109. package/dist/transmit-effect.js +2 -0
  110. package/dist/transmit-effect.js.map +1 -0
  111. package/dist/transmit.d.ts +27 -0
  112. package/dist/transmit.d.ts.map +1 -0
  113. package/dist/transmit.js +105 -0
  114. package/dist/transmit.js.map +1 -0
  115. package/dist/version.d.ts +1 -1
  116. package/dist/version.js +1 -1
  117. package/dist/web/index.d.ts +1 -0
  118. package/dist/web/index.d.ts.map +1 -1
  119. package/dist/web/index.js +1 -0
  120. package/dist/web/index.js.map +1 -1
  121. package/dist/worker.d.ts +1 -1
  122. package/dist/worker.d.ts.map +1 -1
  123. package/dist/worker.js +1 -1
  124. package/dist/worker.js.map +1 -1
  125. package/docs/api.md +199 -20
  126. package/docs/architecture.md +50 -23
  127. package/docs/authorization.md +6 -5
  128. package/docs/benchmarks.md +87 -65
  129. package/docs/browser-protocol.md +62 -3
  130. package/docs/comparisons.md +14 -9
  131. package/docs/configuration.md +2 -2
  132. package/docs/correctness.md +30 -17
  133. package/docs/dashboard.md +6 -6
  134. package/docs/errors-and-recovery.md +12 -12
  135. package/docs/fit.md +3 -0
  136. package/docs/operations.md +33 -19
  137. package/docs/parity.md +126 -47
  138. package/docs/releasing.md +11 -5
  139. package/docs/state-and-lifecycle.md +12 -8
  140. package/docs/support.md +56 -20
  141. package/examples/failure-recovery/actor.ts +6 -8
  142. package/examples/failure-recovery/demo.ts +8 -26
  143. package/examples/failure-recovery/serialization.ts +133 -0
  144. package/examples/quickstart-report.ts +151 -0
  145. package/examples/sqlite-quickstart.ts +76 -16
  146. package/package.json +29 -3
@@ -0,0 +1,133 @@
1
+ import assert from "node:assert/strict"
2
+
3
+ export interface SerializationEvent {
4
+ event: "start" | "finish"
5
+ messageId: string
6
+ attempt: number
7
+ processId: number
8
+ at: number
9
+ }
10
+
11
+ export interface SerializationProof {
12
+ executions: number
13
+ retried: boolean
14
+ supersededOverlap: boolean
15
+ }
16
+
17
+ interface Execution {
18
+ messageId: string
19
+ attempt: number
20
+ processId: number
21
+ startedAt: number
22
+ finishedAt: number
23
+ }
24
+
25
+ export function parseSerializationEvent(line: string): SerializationEvent {
26
+ const event = JSON.parse(line) as Partial<SerializationEvent>
27
+ if (
28
+ (event.event !== "start" && event.event !== "finish") ||
29
+ typeof event.messageId !== "string" ||
30
+ typeof event.attempt !== "number" ||
31
+ typeof event.processId !== "number" ||
32
+ typeof event.at !== "number"
33
+ ) {
34
+ throw new TypeError("invalid serialization event")
35
+ }
36
+ return {
37
+ event: event.event,
38
+ messageId: event.messageId,
39
+ attempt: event.attempt,
40
+ processId: event.processId,
41
+ at: event.at,
42
+ }
43
+ }
44
+
45
+ // One identity commits one state transition at a time. The control file is
46
+ // written outside the transaction, so it records execution attempts rather than
47
+ // commits: a worker that loses its lease keeps running until it notices, and its
48
+ // replacement executes the same message under a higher attempt. The superseded
49
+ // attempt may therefore overlap anything, because its write is fenced out and
50
+ // the committed state is what proves it.
51
+ //
52
+ // Each event carries its attempt and process, so a start pairs with its own
53
+ // finish rather than with whichever finish arrived next. Without that, a
54
+ // superseded attempt finishing late reads as its replacement finishing, and a
55
+ // second message could then overlap a replacement that is still running.
56
+ export function assertSerializedExecution(
57
+ events: readonly SerializationEvent[],
58
+ options: { messageCount: number },
59
+ ): SerializationProof {
60
+ const executions = pairExecutions(events)
61
+
62
+ const messageIds = new Set(executions.map((execution) => execution.messageId))
63
+ assert.equal(
64
+ messageIds.size,
65
+ options.messageCount,
66
+ `expected ${options.messageCount} messages to run, saw ${messageIds.size}`,
67
+ )
68
+
69
+ const survivingAttempt = new Map<string, number>()
70
+ for (const execution of executions) {
71
+ const highest = survivingAttempt.get(execution.messageId) ?? 0
72
+ if (execution.attempt > highest) survivingAttempt.set(execution.messageId, execution.attempt)
73
+ }
74
+ const surviving = executions.filter(
75
+ (execution) => survivingAttempt.get(execution.messageId) === execution.attempt,
76
+ )
77
+
78
+ for (const [index, execution] of surviving.entries()) {
79
+ for (const other of surviving.slice(index + 1)) {
80
+ assert(
81
+ !overlaps(execution, other),
82
+ `${describe(execution)} and ${describe(other)} overlap, and neither was superseded`,
83
+ )
84
+ }
85
+ }
86
+
87
+ const supersededOverlap = executions.some((execution) =>
88
+ executions.some((other) => other !== execution && overlaps(execution, other)),
89
+ )
90
+
91
+ return {
92
+ executions: executions.length,
93
+ retried: executions.length > options.messageCount,
94
+ supersededOverlap,
95
+ }
96
+ }
97
+
98
+ function pairExecutions(events: readonly SerializationEvent[]): Execution[] {
99
+ const started = new Map<string, SerializationEvent>()
100
+ const executions: Execution[] = []
101
+
102
+ for (const event of [...events].sort((left, right) => left.at - right.at)) {
103
+ const key = `${event.messageId}#${event.attempt}#${event.processId}`
104
+ if (event.event === "start") {
105
+ assert(!started.has(key), `${describe(event)} started twice`)
106
+ started.set(key, event)
107
+ continue
108
+ }
109
+ const start = started.get(key)
110
+ assert(start !== undefined, `${describe(event)} finished with no matching start`)
111
+ started.delete(key)
112
+ executions.push({
113
+ messageId: event.messageId,
114
+ attempt: event.attempt,
115
+ processId: event.processId,
116
+ startedAt: start.at,
117
+ finishedAt: event.at,
118
+ })
119
+ }
120
+
121
+ const unfinished = [...started.values()].map(describe)
122
+ assert.equal(unfinished.length, 0, `${unfinished.join(", ")} never wrote a finish`)
123
+
124
+ return executions
125
+ }
126
+
127
+ function overlaps(left: Execution, right: Execution): boolean {
128
+ return left.startedAt < right.finishedAt && right.startedAt < left.finishedAt
129
+ }
130
+
131
+ function describe(execution: { messageId: string; attempt: number }): string {
132
+ return `${execution.messageId} attempt ${execution.attempt}`
133
+ }
@@ -0,0 +1,151 @@
1
+ export interface QuickstartSummary {
2
+ sameIdentityCalls: number
3
+ sameIdentityFinalState: number
4
+ independentIdentitiesOverlapped: boolean
5
+ temporaryStateRemoved: boolean
6
+ }
7
+
8
+ interface QuickstartCheck {
9
+ passed: boolean
10
+ title: string
11
+ detail: readonly string[]
12
+ }
13
+
14
+ const INSTALL_COMMAND = "npm install solid-objects"
15
+ const AGENT_PROMPT = "where would the solid-objects library be best used in this app?"
16
+ const DOCUMENTATION_URL = "https://solidobjects.dev/node"
17
+
18
+ export function formatQuickstartPlan(plan: {
19
+ sameIdentityCalls: number
20
+ actorSource: string
21
+ }): string {
22
+ return [
23
+ "Solid Objects quickstart",
24
+ "",
25
+ "This command will:",
26
+ "",
27
+ " 1. create a temporary SQLite database;",
28
+ ` 2. send ${plan.sameIdentityCalls} concurrent calls to one identity;`,
29
+ " 3. run two other identities at the same time;",
30
+ " 4. close the runtime and delete the temporary database.",
31
+ "",
32
+ "No server, container, or configuration is needed.",
33
+ "",
34
+ "The actor it runs:",
35
+ "",
36
+ ...plan.actorSource.split("\n").map((line) => ` ${line}`.trimEnd()),
37
+ "",
38
+ "",
39
+ ].join("\n")
40
+ }
41
+
42
+ export function formatQuickstartPrompt(): string {
43
+ return "Run it now? [Y/n] "
44
+ }
45
+
46
+ export function answerAllowsRun(answer: string): boolean {
47
+ const value = answer.trim().toLowerCase()
48
+ if (value === "") return true
49
+ return value === "y" || value === "yes"
50
+ }
51
+
52
+ export function formatQuickstartStop(): string {
53
+ return ["", "Nothing ran. No database and no files were created.", ""].join("\n")
54
+ }
55
+
56
+ export function formatQuickstartReport(summary: QuickstartSummary): string {
57
+ const results = checks(summary)
58
+ return [
59
+ "Results",
60
+ "",
61
+ ...results.flatMap(checkLines),
62
+ "",
63
+ "Each line above is an assertion, not a print. The command exits with a",
64
+ "non-zero code when one of them fails.",
65
+ "",
66
+ ...meaning(results),
67
+ "Add it to your app",
68
+ "",
69
+ ` ${INSTALL_COMMAND}`,
70
+ "",
71
+ "Or tell your agent",
72
+ "",
73
+ ` ${AGENT_PROMPT}`,
74
+ "",
75
+ `Docs: ${DOCUMENTATION_URL}`,
76
+ "",
77
+ ].join("\n")
78
+ }
79
+
80
+ function meaning(results: readonly QuickstartCheck[]): string[] {
81
+ if (results.some((check) => !check.passed)) return []
82
+ return [
83
+ "What each PASS means",
84
+ "",
85
+ " Two requests on the same cart cannot overwrite each other.",
86
+ " That identity has one durable mailbox, so its calls commit one at a",
87
+ " time and no update is lost.",
88
+ "",
89
+ " Unrelated identities do not wait for that mailbox.",
90
+ " The order is per identity, not global.",
91
+ "",
92
+ " The state lives in an ordinary SQL database, so it survives a restart.",
93
+ "",
94
+ ]
95
+ }
96
+
97
+ function checkLines(check: QuickstartCheck): string[] {
98
+ const result = check.passed ? "PASS" : "FAIL"
99
+ return [`${result} ${check.title}`, ...check.detail.map((line) => ` ${line}`)]
100
+ }
101
+
102
+ function checks(summary: QuickstartSummary): QuickstartCheck[] {
103
+ return [
104
+ {
105
+ passed: summary.sameIdentityFinalState === summary.sameIdentityCalls,
106
+ title: `${summary.sameIdentityCalls} concurrent calls to one identity`,
107
+ detail: sameIdentityDetail(summary),
108
+ },
109
+ {
110
+ passed: summary.independentIdentitiesOverlapped,
111
+ title: "Two different identities ran at the same time",
112
+ detail: overlapDetail(summary),
113
+ },
114
+ {
115
+ passed: summary.temporaryStateRemoved,
116
+ title: "Temporary state removed",
117
+ detail: cleanupDetail(summary),
118
+ },
119
+ ]
120
+ }
121
+
122
+ function sameIdentityDetail(summary: QuickstartSummary): string[] {
123
+ if (summary.sameIdentityFinalState !== summary.sameIdentityCalls) {
124
+ return [
125
+ `The committed state is ${summary.sameIdentityFinalState} after ${summary.sameIdentityCalls} calls.`,
126
+ "The runtime lost an update.",
127
+ ]
128
+ }
129
+ return [
130
+ "They ran in order on one mailbox.",
131
+ `The committed state is ${summary.sameIdentityFinalState}.`,
132
+ `The return values were the complete sequence 1 through ${summary.sameIdentityCalls}.`,
133
+ ]
134
+ }
135
+
136
+ function overlapDetail(summary: QuickstartSummary): string[] {
137
+ if (!summary.independentIdentitiesOverlapped) {
138
+ return ["Their execution windows did not overlap."]
139
+ }
140
+ return [
141
+ "Their execution windows overlapped, so an unrelated identity",
142
+ "never waits behind this one.",
143
+ ]
144
+ }
145
+
146
+ function cleanupDetail(summary: QuickstartSummary): string[] {
147
+ if (!summary.temporaryStateRemoved) {
148
+ return ["The temporary SQLite database is still on disk."]
149
+ }
150
+ return ["The scoped temporary SQLite database was deleted at exit."]
151
+ }
@@ -6,6 +6,17 @@ import { join, resolve } from "node:path"
6
6
  import { fileURLToPath } from "node:url"
7
7
  import { Actor, createRuntime } from "solid-objects"
8
8
  import { sqlite } from "solid-objects/database/sqlite"
9
+ import { createInterface } from "node:readline/promises"
10
+ import {
11
+ answerAllowsRun,
12
+ formatQuickstartPlan,
13
+ formatQuickstartPrompt,
14
+ formatQuickstartReport,
15
+ formatQuickstartStop,
16
+ type QuickstartSummary,
17
+ } from "./quickstart-report.js"
18
+
19
+ const SAME_IDENTITY_CALLS = 25
9
20
 
10
21
  class Counter extends Actor {
11
22
  static override readonly actorType = "QuickstartCounter"
@@ -27,12 +38,61 @@ class Counter extends Actor {
27
38
  }
28
39
  }
29
40
 
41
+ const COUNTER_SOURCE = `class Counter extends Actor {
42
+ static override readonly actorType = "QuickstartCounter"
43
+
44
+ count = 0
45
+
46
+ increment(): number {
47
+ this.count += 1
48
+ return this.count
49
+ }
50
+
51
+ async pause({ milliseconds }: { milliseconds: number }) {
52
+ const startedAt = performance.now()
53
+ await new Promise((done) => setTimeout(done, milliseconds))
54
+ return { startedAt, finishedAt: performance.now() }
55
+ }
56
+ }`
57
+
58
+ async function confirmRun(options: {
59
+ format?: "report" | "json"
60
+ confirm?: () => boolean | Promise<boolean>
61
+ }): Promise<boolean> {
62
+ if (options.format === "json") return true
63
+ if (options.confirm) return options.confirm()
64
+ if (!process.stdin.isTTY) return true
65
+ const questions = createInterface({ input: process.stdin, output: process.stdout })
66
+ try {
67
+ return answerAllowsRun(await questions.question(formatQuickstartPrompt()))
68
+ } catch {
69
+ return false
70
+ } finally {
71
+ questions.close()
72
+ }
73
+ }
74
+
30
75
  export async function runQuickstart(
31
76
  options: {
32
77
  signal?: AbortSignal
33
78
  write?: (value: string) => void
79
+ format?: "report" | "json"
80
+ confirm?: () => boolean | Promise<boolean>
34
81
  } = {},
35
82
  ): Promise<void> {
83
+ const write = options.write ?? ((value: string) => process.stdout.write(value))
84
+ if (options.format !== "json") {
85
+ write(
86
+ formatQuickstartPlan({
87
+ sameIdentityCalls: SAME_IDENTITY_CALLS,
88
+ actorSource: COUNTER_SOURCE,
89
+ }),
90
+ )
91
+ }
92
+ if (!(await confirmRun(options))) {
93
+ write(formatQuickstartStop())
94
+ return
95
+ }
36
96
  const directory = await mkdtemp(join(tmpdir(), "solid-objects-quickstart-"))
37
97
  const databasePath = join(directory, "state.sqlite3")
38
98
  const runtime = createRuntime({
@@ -58,13 +118,15 @@ export async function runQuickstart(
58
118
  running = runtime.run(shutdown.signal)
59
119
 
60
120
  const counter = runtime.ref(Counter, "room-1")
61
- const results = await Promise.all(Array.from({ length: 25 }, () => counter.increment()))
121
+ const results = await Promise.all(
122
+ Array.from({ length: SAME_IDENTITY_CALLS }, () => counter.increment()),
123
+ )
62
124
  assert.deepEqual(
63
125
  [...results].sort((left, right) => left - right),
64
- Array.from({ length: 25 }, (_value, index) => index + 1),
126
+ Array.from({ length: SAME_IDENTITY_CALLS }, (_value, index) => index + 1),
65
127
  )
66
128
  sameIdentityFinalState = await counter.count
67
- assert.equal(sameIdentityFinalState, 25)
129
+ assert.equal(sameIdentityFinalState, SAME_IDENTITY_CALLS)
68
130
 
69
131
  const pauses = await Promise.all([
70
132
  runtime.ref(Counter, "room-2").send.pause({ milliseconds: 100 }),
@@ -89,19 +151,17 @@ export async function runQuickstart(
89
151
  }
90
152
 
91
153
  assert.equal(existsSync(directory), false)
92
- const write = options.write ?? ((value: string) => process.stdout.write(value))
93
- write(
94
- `${JSON.stringify(
95
- {
96
- sameIdentityCalls: 25,
97
- sameIdentityFinalState,
98
- independentIdentitiesOverlapped,
99
- temporaryStateRemoved: true,
100
- },
101
- null,
102
- 2,
103
- )}\n`,
104
- )
154
+ const summary: QuickstartSummary = {
155
+ sameIdentityCalls: SAME_IDENTITY_CALLS,
156
+ sameIdentityFinalState,
157
+ independentIdentitiesOverlapped,
158
+ temporaryStateRemoved: true,
159
+ }
160
+ if (options.format === "json") {
161
+ write(`${JSON.stringify(summary, null, 2)}\n`)
162
+ return
163
+ }
164
+ write(formatQuickstartReport(summary))
105
165
  }
106
166
 
107
167
  if (process.argv[1] && fileURLToPath(import.meta.url) === resolve(process.argv[1])) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "solid-objects",
3
- "version": "0.13.2",
3
+ "version": "0.14.0",
4
4
  "description": "Race-free realtime state per application identity, backed by your SQL database",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -23,7 +23,7 @@
23
23
  "url": "git+https://github.com/cardmagic/solid-objects-js.git"
24
24
  },
25
25
  "engines": {
26
- "node": ">=24.15.0"
26
+ "node": ">=24.4.0"
27
27
  },
28
28
  "packageManager": "pnpm@11.11.0",
29
29
  "bin": {
@@ -46,6 +46,14 @@
46
46
  "types": "./dist/database/sqlite.d.ts",
47
47
  "import": "./dist/database/sqlite.js"
48
48
  },
49
+ "./database/sqlite-wasm": {
50
+ "types": "./dist/database/sqlite-wasm.d.ts",
51
+ "import": "./dist/database/sqlite-wasm.js"
52
+ },
53
+ "./database/shared-sqlite-wasm": {
54
+ "types": "./dist/database/shared-sqlite-wasm.d.ts",
55
+ "import": "./dist/database/shared-sqlite-wasm.js"
56
+ },
49
57
  "./database/postgresql": {
50
58
  "types": "./dist/database/postgresql.d.ts",
51
59
  "import": "./dist/database/postgresql.js"
@@ -62,6 +70,18 @@
62
70
  "types": "./dist/browser/index.d.ts",
63
71
  "import": "./dist/browser/index.js"
64
72
  },
73
+ "./browser/host": {
74
+ "types": "./dist/browser/host.d.ts",
75
+ "import": "./dist/browser/host.js"
76
+ },
77
+ "./browser/tab-host": {
78
+ "types": "./dist/browser/tab-host.d.ts",
79
+ "import": "./dist/browser/tab-host.js"
80
+ },
81
+ "./transmit": {
82
+ "types": "./dist/transmit.d.ts",
83
+ "import": "./dist/transmit.js"
84
+ },
65
85
  "./web": {
66
86
  "types": "./dist/web/index.d.ts",
67
87
  "import": "./dist/web/index.js"
@@ -69,7 +89,8 @@
69
89
  },
70
90
  "scripts": {
71
91
  "build": "pnpm run clean && tsc -p tsconfig.build.json && tsc -p tsconfig.quickstart-build.json && node scripts/prepare-executable.mjs",
72
- "check": "pnpm run check:parameters && pnpm run check:documentation && tsc -p tsconfig.json --noEmit && tsc -p tsconfig.examples.json --noEmit",
92
+ "check": "pnpm run check:parameters && pnpm run check:documentation && pnpm run check:browser-imports && tsc -p tsconfig.json --noEmit && tsc -p tsconfig.examples.json --noEmit",
93
+ "check:browser-imports": "node scripts/check-browser-imports.mjs",
73
94
  "check:documentation": "node scripts/check-documentation.mjs",
74
95
  "check:parameters": "node scripts/check-parameter-style.mjs",
75
96
  "clean": "node scripts/clean.mjs",
@@ -91,6 +112,7 @@
91
112
  },
92
113
  "devDependencies": {
93
114
  "@playwright/test": "^1.62.1",
115
+ "@sqlite.org/sqlite-wasm": "3.53.0-build1",
94
116
  "@types/node": "^24.0.0",
95
117
  "@types/pg": "^8.21.0",
96
118
  "@types/ws": "^8.18.1",
@@ -104,11 +126,15 @@
104
126
  "ws": "^8.21.3"
105
127
  },
106
128
  "peerDependencies": {
129
+ "@sqlite.org/sqlite-wasm": ">=3.50.0-build1",
107
130
  "mysql2": "^3.23.3",
108
131
  "pg": "^8.23.0",
109
132
  "redis": "^6.2.1"
110
133
  },
111
134
  "peerDependenciesMeta": {
135
+ "@sqlite.org/sqlite-wasm": {
136
+ "optional": true
137
+ },
112
138
  "mysql2": {
113
139
  "optional": true
114
140
  },