@livestore/sqlite-wasm 0.4.0-dev.9 → 0.5.0-dev.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 (93) hide show
  1. package/README.md +1 -1
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/FacadeVFS.d.ts +0 -4
  4. package/dist/FacadeVFS.d.ts.map +1 -1
  5. package/dist/FacadeVFS.js +13 -17
  6. package/dist/FacadeVFS.js.map +1 -1
  7. package/dist/browser/mod.d.ts +13 -6
  8. package/dist/browser/mod.d.ts.map +1 -1
  9. package/dist/browser/mod.js +48 -42
  10. package/dist/browser/mod.js.map +1 -1
  11. package/dist/browser/opfs/AccessHandlePoolVFS.d.ts +24 -18
  12. package/dist/browser/opfs/AccessHandlePoolVFS.d.ts.map +1 -1
  13. package/dist/browser/opfs/AccessHandlePoolVFS.js +178 -166
  14. package/dist/browser/opfs/AccessHandlePoolVFS.js.map +1 -1
  15. package/dist/browser/opfs/index.d.ts +3 -2
  16. package/dist/browser/opfs/index.d.ts.map +1 -1
  17. package/dist/browser/opfs/index.js +3 -3
  18. package/dist/browser/opfs/index.js.map +1 -1
  19. package/dist/browser/opfs/opfs-sah-pool.d.ts +1 -1
  20. package/dist/browser/opfs/opfs-sah-pool.d.ts.map +1 -1
  21. package/dist/browser/opfs/opfs-sah-pool.js +4 -4
  22. package/dist/browser/opfs/opfs-sah-pool.js.map +1 -1
  23. package/dist/cf/CloudflareDurableObjectVFS.d.ts +104 -0
  24. package/dist/cf/CloudflareDurableObjectVFS.d.ts.map +1 -0
  25. package/dist/cf/CloudflareDurableObjectVFS.js +283 -0
  26. package/dist/cf/CloudflareDurableObjectVFS.js.map +1 -0
  27. package/dist/cf/CloudflareWorkerVFS.d.ts.map +1 -1
  28. package/dist/cf/CloudflareWorkerVFS.js +29 -28
  29. package/dist/cf/CloudflareWorkerVFS.js.map +1 -1
  30. package/dist/cf/mod.d.ts +3 -4
  31. package/dist/cf/mod.d.ts.map +1 -1
  32. package/dist/cf/mod.js +6 -14
  33. package/dist/cf/mod.js.map +1 -1
  34. package/dist/cf/test/async-storage/cloudflare-worker-vfs-advanced.test.js +6 -5
  35. package/dist/cf/test/async-storage/cloudflare-worker-vfs-advanced.test.js.map +1 -1
  36. package/dist/cf/test/async-storage/cloudflare-worker-vfs-core.test.js +4 -4
  37. package/dist/cf/test/async-storage/cloudflare-worker-vfs-core.test.js.map +1 -1
  38. package/dist/cf/test/async-storage/cloudflare-worker-vfs-integration.test.js +4 -4
  39. package/dist/cf/test/async-storage/cloudflare-worker-vfs-integration.test.js.map +1 -1
  40. package/dist/cf/test/async-storage/cloudflare-worker-vfs-reliability.test.js +4 -4
  41. package/dist/cf/test/async-storage/cloudflare-worker-vfs-reliability.test.js.map +1 -1
  42. package/dist/cf/test/sql/cloudflare-sql-vfs-core.test.js +195 -180
  43. package/dist/cf/test/sql/cloudflare-sql-vfs-core.test.js.map +1 -1
  44. package/dist/in-memory-vfs.d.ts.map +1 -1
  45. package/dist/in-memory-vfs.js +0 -1
  46. package/dist/in-memory-vfs.js.map +1 -1
  47. package/dist/load-wasm/mod.node.js +1 -1
  48. package/dist/load-wasm/mod.node.js.map +1 -1
  49. package/dist/load-wasm/mod.workerd.d.ts.map +1 -1
  50. package/dist/load-wasm/mod.workerd.js +2 -0
  51. package/dist/load-wasm/mod.workerd.js.map +1 -1
  52. package/dist/make-sqlite-db.d.ts.map +1 -1
  53. package/dist/make-sqlite-db.js +18 -9
  54. package/dist/make-sqlite-db.js.map +1 -1
  55. package/dist/node/NodeFS.d.ts.map +1 -1
  56. package/dist/node/NodeFS.js +14 -14
  57. package/dist/node/NodeFS.js.map +1 -1
  58. package/dist/node/mod.d.ts.map +1 -1
  59. package/dist/node/mod.js +3 -3
  60. package/dist/node/mod.js.map +1 -1
  61. package/package.json +48 -18
  62. package/src/FacadeVFS.ts +13 -17
  63. package/src/browser/mod.ts +38 -13
  64. package/src/browser/opfs/AccessHandlePoolVFS.ts +374 -268
  65. package/src/browser/opfs/index.ts +5 -4
  66. package/src/browser/opfs/opfs-sah-pool.ts +4 -4
  67. package/src/cf/CloudflareDurableObjectVFS.ts +324 -0
  68. package/src/cf/CloudflareWorkerVFS.ts +41 -39
  69. package/src/cf/README.md +3 -3
  70. package/src/cf/mod.ts +12 -17
  71. package/src/cf/test/README.md +63 -37
  72. package/src/cf/test/async-storage/cloudflare-worker-vfs-advanced.test.ts +8 -5
  73. package/src/cf/test/async-storage/cloudflare-worker-vfs-core.test.ts +6 -4
  74. package/src/cf/test/async-storage/cloudflare-worker-vfs-integration.test.ts +6 -4
  75. package/src/cf/test/async-storage/cloudflare-worker-vfs-reliability.test.ts +6 -4
  76. package/src/cf/test/sql/cloudflare-sql-vfs-core.test.ts +232 -198
  77. package/src/in-memory-vfs.ts +0 -1
  78. package/src/load-wasm/mod.node.ts +1 -1
  79. package/src/load-wasm/mod.workerd.ts +2 -1
  80. package/src/make-sqlite-db.ts +21 -9
  81. package/src/node/NodeFS.ts +25 -24
  82. package/src/node/mod.ts +3 -3
  83. package/dist/cf/BlockManager.d.ts +0 -61
  84. package/dist/cf/BlockManager.d.ts.map +0 -1
  85. package/dist/cf/BlockManager.js +0 -157
  86. package/dist/cf/BlockManager.js.map +0 -1
  87. package/dist/cf/CloudflareSqlVFS.d.ts +0 -51
  88. package/dist/cf/CloudflareSqlVFS.d.ts.map +0 -1
  89. package/dist/cf/CloudflareSqlVFS.js +0 -351
  90. package/dist/cf/CloudflareSqlVFS.js.map +0 -1
  91. package/src/ambient.d.ts +0 -18
  92. package/src/cf/BlockManager.ts +0 -225
  93. package/src/cf/CloudflareSqlVFS.ts +0 -450
package/src/cf/mod.ts CHANGED
@@ -1,16 +1,20 @@
1
1
  // import path from 'node:path'
2
2
 
3
- import { type MakeSqliteDb, type PersistenceInfo, type SqliteDb, UnexpectedError } from '@livestore/common'
3
+ import { type MakeSqliteDb, type PersistenceInfo, type SqliteDb, UnknownError } from '@livestore/common'
4
4
  import type { CfTypes } from '@livestore/common-cf'
5
5
  import { Effect } from '@livestore/utils/effect'
6
6
  import type * as WaSqlite from '@livestore/wa-sqlite'
7
7
  import type { MemoryVFS } from '@livestore/wa-sqlite/src/examples/MemoryVFS.js'
8
+
8
9
  import { makeInMemoryDb } from '../in-memory-vfs.ts'
9
10
  import { makeSqliteDb } from '../make-sqlite-db.ts'
10
- import { CloudflareSqlVFS } from './CloudflareSqlVFS.ts'
11
+ import { CloudflareDurableObjectVFS } from './CloudflareDurableObjectVFS.ts'
11
12
 
12
- export { BlockManager } from './BlockManager.ts'
13
- export { CloudflareSqlVFS } from './CloudflareSqlVFS.ts'
13
+ export {
14
+ CloudflareDurableObjectVFS,
15
+ PAGE_SIZE as CF_SQL_VFS_PAGE_SIZE,
16
+ REQUIRED_PRAGMAS as CF_SQL_VFS_REQUIRED_PRAGMAS,
17
+ } from './CloudflareDurableObjectVFS.ts'
14
18
  export { CloudflareWorkerVFS } from './CloudflareWorkerVFS.ts'
15
19
 
16
20
  export type CloudflareDatabaseMetadataInMemory = {
@@ -24,8 +28,7 @@ export type CloudflareDatabaseMetadataInMemory = {
24
28
 
25
29
  export type CloudflareDatabaseMetadataFs = {
26
30
  _tag: 'storage'
27
- // vfs: CloudflareWorkerVFS
28
- vfs: CloudflareSqlVFS
31
+ vfs: CloudflareDurableObjectVFS
29
32
  dbPointer: number
30
33
  persistenceInfo: PersistenceInfo
31
34
  deleteDb: () => void
@@ -115,18 +118,10 @@ const makeCloudflareFsDb = ({
115
118
  // If this is becoming a problem, we can use a hashed version of the directory name
116
119
  const vfsName = `cf-do-sqlite-${fileName}`
117
120
  if (sqlite3.vfs_registered.has(vfsName) === false) {
118
- // TODO refactor with Effect FileSystem instead of using `node:fs` directly inside of CloudflareWorkerVFS
119
- // const nodeFsVfs = new CloudflareWorkerVFS(vfsName, storage, (sqlite3 as any).module)
120
- const nodeFsVfs = new CloudflareSqlVFS(vfsName, storage.sql, (sqlite3 as any).module)
121
-
122
- // Initialize the VFS schema before registering it
123
- const isReady = yield* Effect.promise(() => nodeFsVfs.isReady())
124
- if (!isReady) {
125
- throw new Error(`Failed to initialize CloudflareSqlVFS for ${vfsName}`)
126
- }
121
+ const vfs = new CloudflareDurableObjectVFS(vfsName, storage.sql, (sqlite3 as any).module)
127
122
 
128
123
  // @ts-expect-error TODO fix types
129
- sqlite3.vfs_register(nodeFsVfs, false)
124
+ sqlite3.vfs_register(vfs, false)
130
125
  }
131
126
 
132
127
  // yield* fs.makeDirectory(directory, { recursive: true })
@@ -140,4 +135,4 @@ const makeCloudflareFsDb = ({
140
135
  const dbPointer = sqlite3.open_v2Sync(fileName, undefined, vfsName)
141
136
 
142
137
  return { dbPointer, vfs: {} as UNUSED<'only needed in web adapter currently and should longer-term be removed'> }
143
- }).pipe(UnexpectedError.mapToUnexpectedError)
138
+ }).pipe(UnknownError.mapToUnknownError)
@@ -5,11 +5,13 @@ This directory contains comprehensive tests for both SQLite WASM VFS implementat
5
5
  ## Directory Structure
6
6
 
7
7
  ### `/sql/` - SQL Storage Tests
8
- Tests for the CloudflareSqlVFS implementation, which uses Cloudflare's DurableObject SQL API for storage.
8
+
9
+ Tests for the CloudflareDurableObjectVFS implementation, which uses Cloudflare's [SQLite in DurableObjects](https://developers.cloudflare.com/durable-objects/api/sql-storage/) for storage.
9
10
 
10
11
  - **`cloudflare-sql-vfs-core.test.ts`** - Core SQL VFS functionality tests
11
12
 
12
- ### `/async-storage/` - Async Storage Tests
13
+ ### `/async-storage/` - Async Storage Tests
14
+
13
15
  Tests for the CloudflareWorkerVFS implementation, which uses DurableObjectStorage (key-value) for file storage.
14
16
 
15
17
  - **`cloudflare-worker-vfs-core.test.ts`** - Basic VFS operations (open, read, write, close, sync)
@@ -20,19 +22,22 @@ Tests for the CloudflareWorkerVFS implementation, which uses DurableObjectStorag
20
22
  ## Test Architecture
21
23
 
22
24
  ### Testing Framework
23
- - **Vitest** with **@cloudflare/vitest-pool-workers** for Workers runtime testing
24
- - **Isolated Storage** - Each test gets fresh storage instances
25
- - **Real Runtime** - Tests run in the actual Cloudflare Workers runtime environment
25
+
26
+ - **Vitest** in the Node test environment
27
+ - **Mocked Cloudflare storage interfaces** - Tests provide in-memory `DurableObjectStorage` and SQL storage doubles
28
+ - **Per-test setup** - Each test creates fresh mock storage and VFS instances
26
29
 
27
30
  ## VFS Implementation Comparison
28
31
 
29
- ### SQL Storage VFS (`CloudflareSqlVFS`)
30
- - **Backend**: Cloudflare DurableObject SQL API
31
- - **Storage Model**: Relational tables with blocks and metadata
32
- - **Advantages**: ACID transactions, complex queries, relational integrity
32
+ ### SQL Storage VFS (`CloudflareDurableObjectVFS`)
33
+
34
+ - **Backend**: Cloudflare's SQLite in Durable Objects
35
+ - **Storage Model**: Single `vfs_pages` table keyed by file path and page number
36
+ - **Advantages**: Simple synchronous SQL storage with direct page lookups
33
37
  - **Use Case**: Applications requiring complex data relationships
34
38
 
35
- ### Async Storage VFS (`CloudflareWorkerVFS`)
39
+ ### Async Storage VFS (`CloudflareWorkerVFS`)
40
+
36
41
  - **Backend**: DurableObjectStorage (key-value)
37
42
  - **Storage Model**: 64 KiB chunks with LRU caching
38
43
  - **Advantages**: Simple API, optimized for large files, better caching
@@ -41,11 +46,14 @@ Tests for the CloudflareWorkerVFS implementation, which uses DurableObjectStorag
41
46
  ## Key Design Decisions Tested
42
47
 
43
48
  ### SQL Storage Approach
44
- - **Block-based Storage**: Files stored as blocks in SQL tables
45
- - **Metadata Management**: File metadata in dedicated tables
46
- - **Transaction Safety**: ACID compliance for data integrity
49
+
50
+ - **Page-based Storage**: SQLite pages stored directly in `vfs_pages`
51
+ - **File-path Isolation**: Each logical SQLite file is scoped by `file_path`
52
+ - **Handle Tracking**: Open SQLite file handles map back to persisted file paths
53
+ - **Transaction Model**: Page writes are persisted directly through Durable Object SQL
47
54
 
48
55
  ### Async Storage Approach
56
+
49
57
  - **64 KiB Chunking Strategy**: Optimized for SQLite I/O patterns
50
58
  - **Synchronous Interface with Async Backend**: Aggressive caching + background sync
51
59
  - **Memory Management**: LRU cache for chunks, complete metadata cache
@@ -54,14 +62,11 @@ Tests for the CloudflareWorkerVFS implementation, which uses DurableObjectStorag
54
62
  ## Running Tests
55
63
 
56
64
  ### Prerequisites
65
+
57
66
  1. Install dependencies:
58
- ```bash
59
- pnpm install
60
- ```
61
67
 
62
- 2. Ensure Wrangler configuration is correct:
63
68
  ```bash
64
- # Check wrangler.toml exists and has correct Durable Object bindings
69
+ pnpm install
65
70
  ```
66
71
 
67
72
  ### Test Commands
@@ -90,30 +95,33 @@ pnpm test --coverage
90
95
 
91
96
  ### Test Environment
92
97
 
93
- - **Runtime**: Cloudflare Workers (via workerd)
94
- - **Storage**: Isolated per-test storage instances
98
+ - **Runtime**: Node via Vitest
99
+ - **Storage**: Mocked Durable Object storage and SQL storage instances created per test
100
+ - **Scope**: Unit/integration coverage for VFS behavior against Cloudflare-shaped interfaces, not workerd runtime coverage
95
101
 
96
102
  ## Test Structure
97
103
 
98
104
  ### SQL Storage Test Pattern
105
+
99
106
  ```typescript
100
107
  import { describe, it, expect, beforeEach } from 'vitest'
101
- import { type Cf, CloudflareSqlVFS } from '../../mod.ts'
108
+ import type { CfTypes } from '@livestore/common-cf'
109
+ import { CloudflareDurableObjectVFS } from '../../mod.ts'
102
110
 
103
111
  describe('SQL VFS Test Suite', () => {
104
- let vfs: CloudflareSqlVFS
105
- let mockSql: Cf.SqlStorage
112
+ let vfs: CloudflareDurableObjectVFS
113
+ let mockSql: CfTypes.SqlStorage
106
114
  let queryLog: string[]
107
115
 
108
116
  beforeEach(async () => {
109
117
  // Setup mock SQL storage
110
118
  mockSql = {
111
119
  exec: (query: string, ...bindings: any[]) => {
112
- // Mock SQL implementation
113
- }
120
+ // Mock SQL implementation for vfs_pages(file_path, page_no, page_data)
121
+ },
114
122
  }
115
-
116
- vfs = new CloudflareSqlVFS('test-vfs', mockSql, {})
123
+
124
+ vfs = new CloudflareDurableObjectVFS('test-vfs', mockSql, {})
117
125
  await vfs.isReady()
118
126
  })
119
127
 
@@ -122,6 +130,7 @@ describe('SQL VFS Test Suite', () => {
122
130
  ```
123
131
 
124
132
  ### Async Storage Test Pattern
133
+
125
134
  ```typescript
126
135
  import { describe, it, expect, beforeEach } from 'vitest'
127
136
  import { type Cf, CloudflareWorkerVFS } from '../../mod.ts'
@@ -133,12 +142,18 @@ describe('Async Storage VFS Test Suite', () => {
133
142
  beforeEach(async () => {
134
143
  // Setup mock DurableObjectStorage
135
144
  mockStorage = {
136
- get: async (key) => { /* mock implementation */ },
137
- put: async (key, value) => { /* mock implementation */ },
138
- delete: async (key) => { /* mock implementation */ },
145
+ get: async (key) => {
146
+ /* mock implementation */
147
+ },
148
+ put: async (key, value) => {
149
+ /* mock implementation */
150
+ },
151
+ delete: async (key) => {
152
+ /* mock implementation */
153
+ },
139
154
  // ... other methods
140
155
  }
141
-
156
+
142
157
  vfs = new CloudflareWorkerVFS('test-vfs', mockStorage, {})
143
158
  await vfs.isReady()
144
159
  })
@@ -150,12 +165,14 @@ describe('Async Storage VFS Test Suite', () => {
150
165
  ## Performance Benchmarks
151
166
 
152
167
  ### Metrics Tracked
168
+
153
169
  - **Throughput**: Operations per second
154
- - **Latency**: Response times for various operations
170
+ - **Latency**: Response times for various operations
155
171
  - **Memory Usage**: Cache effectiveness and memory consumption
156
172
  - **Storage Efficiency**: Data compression and chunking effectiveness
157
173
 
158
174
  ### Benchmark Comparisons
175
+
159
176
  - SQL vs Async Storage performance characteristics
160
177
  - Memory usage patterns between implementations
161
178
  - Scalability under different workloads
@@ -163,31 +180,35 @@ describe('Async Storage VFS Test Suite', () => {
163
180
  ## Test Data Cleanup
164
181
 
165
182
  ### Automatic Cleanup
166
- - **Isolated Storage**: Each test gets fresh storage instances
183
+
184
+ - **Fresh mock storage**: Each test creates new in-memory storage instances
167
185
  - **Temporary Files**: Cleaned up automatically
168
186
  - **Cache Management**: Memory caches cleared between tests
169
187
 
170
188
  ## Debugging Tests
171
189
 
172
190
  ### Logging
191
+
173
192
  - Use `console.log` for debugging (visible in test output)
174
193
  - VFS statistics available via `vfs.getStats()`
175
194
  - Storage operations logged in development mode
176
195
 
177
196
  ### Common Issues
178
- 1. **SQL Schema Issues**: Ensure proper table creation and constraints
197
+
198
+ 1. **SQL Schema Issues**: Ensure `vfs_pages(file_path, page_no, page_data)` is created as expected
179
199
  2. **Cache Misses**: Verify proper preloading in VFS initialization
180
- 3. **Async/Sync Mismatch**: Check async operations are properly handled
200
+ 3. **Handle/Path Mismatch**: Verify reads and writes use the path captured during `jOpen`
181
201
  4. **Storage Limits**: Verify chunk sizes and storage capacity
182
202
 
183
203
  ### Test Debugging
204
+
184
205
  ```typescript
185
206
  // SQL VFS debugging
186
207
  console.log('Query log:', queryLog)
187
208
  const stats = vfs.getStats()
188
209
  console.log('VFS Stats:', stats)
189
210
 
190
- // Async Storage VFS debugging
211
+ // Async Storage VFS debugging
191
212
  const metadata = await storage.get('file:/test/file.db:meta')
192
213
  console.log('File metadata:', metadata)
193
214
  ```
@@ -195,12 +216,15 @@ console.log('File metadata:', metadata)
195
216
  ## Future Enhancements
196
217
 
197
218
  ### Planned Test Additions
219
+
198
220
  1. **Performance Comparisons**: Direct SQL vs Async Storage benchmarks
199
221
  2. **Migration Tests**: Converting between storage backends
200
222
  3. **Stress Tests**: High-load scenarios for both implementations
201
223
  4. **Real SQLite Integration**: Tests with actual SQLite WASM
224
+ 5. **Workers Runtime Coverage**: Add dedicated workerd-based tests if runtime bindings or Wrangler configuration need validation
202
225
 
203
226
  ### Implementation Improvements
227
+
204
228
  1. **Hybrid Approach**: Combining SQL and async storage benefits
205
229
  2. **Compression Testing**: Data compression effectiveness
206
230
  3. **Caching Strategies**: Cross-implementation cache optimization
@@ -208,6 +232,7 @@ console.log('File metadata:', metadata)
208
232
  ## Contributing
209
233
 
210
234
  When adding new tests:
235
+
211
236
  1. Choose the appropriate location:
212
237
  - SQL storage tests: `/src/cf/test/sql/`
213
238
  - Async storage tests: `/src/cf/test/async-storage/`
@@ -217,8 +242,9 @@ When adding new tests:
217
242
  5. Update this documentation
218
243
 
219
244
  ### Test Guidelines
245
+
220
246
  - **Isolation**: Each test should be independent
221
247
  - **Implementation Specific**: Tests should target specific VFS features
222
248
  - **Assertions**: Use meaningful assertions with clear error messages
223
249
  - **Coverage**: Aim for comprehensive coverage of edge cases
224
- - **Performance**: Consider performance implications of each approach
250
+ - **Performance**: Consider performance implications of each approach
@@ -1,8 +1,10 @@
1
1
  /// <reference types="vitest/globals" />
2
2
 
3
+ import { beforeEach, describe, expect, it } from 'vitest'
4
+
3
5
  import type { CfTypes } from '@livestore/common-cf'
4
6
  import * as VFS from '@livestore/wa-sqlite/src/VFS.js'
5
- import { beforeEach, describe, expect, it } from 'vitest'
7
+
6
8
  import { CloudflareWorkerVFS } from '../../mod.ts'
7
9
 
8
10
  describe('CloudflareWorkerVFS - Advanced Features', () => {
@@ -15,7 +17,7 @@ describe('CloudflareWorkerVFS - Advanced Features', () => {
15
17
 
16
18
  mockStorage = {
17
19
  get: (async (_key: string | string[]) => {
18
- if (Array.isArray(_key)) {
20
+ if (Array.isArray(_key) === true) {
19
21
  return new Map()
20
22
  }
21
23
  return storageData.get(_key)
@@ -32,10 +34,10 @@ describe('CloudflareWorkerVFS - Advanced Features', () => {
32
34
  },
33
35
 
34
36
  delete: (async (_key: string | string[]) => {
35
- if (Array.isArray(_key)) {
37
+ if (Array.isArray(_key) === true) {
36
38
  let count = 0
37
39
  for (const k of _key) {
38
- if (storageData.delete(k)) count++
40
+ if (storageData.delete(k) === true) count++
39
41
  }
40
42
  return count
41
43
  } else {
@@ -156,7 +158,8 @@ describe('CloudflareWorkerVFS - Advanced Features', () => {
156
158
  expect(vfs.jClose(fileId)).toBe(VFS.SQLITE_OK)
157
159
  })
158
160
 
159
- it('should handle large files that exceed cache capacity', async () => {
161
+ // TODO: Remove retry once flaky timeout is investigated (https://github.com/livestorejs/livestore/issues/1020)
162
+ it('should handle large files that exceed cache capacity', { retry: 3, timeout: 10000 }, async () => {
160
163
  const path = '/test/cache-overflow.db'
161
164
  const fileId = 1
162
165
  const flags = VFS.SQLITE_OPEN_CREATE | VFS.SQLITE_OPEN_READWRITE
@@ -1,8 +1,10 @@
1
1
  /// <reference types="vitest/globals" />
2
2
 
3
+ import { beforeEach, describe, expect, it } from 'vitest'
4
+
3
5
  import type { CfTypes } from '@livestore/common-cf'
4
6
  import * as VFS from '@livestore/wa-sqlite/src/VFS.js'
5
- import { beforeEach, describe, expect, it } from 'vitest'
7
+
6
8
  import { CloudflareWorkerVFS } from '../../mod.ts'
7
9
 
8
10
  describe('CloudflareWorkerVFS - Core Functionality', () => {
@@ -15,7 +17,7 @@ describe('CloudflareWorkerVFS - Core Functionality', () => {
15
17
 
16
18
  mockStorage = {
17
19
  get: (async (_key: string | string[]) => {
18
- if (Array.isArray(_key)) {
20
+ if (Array.isArray(_key) === true) {
19
21
  return new Map()
20
22
  }
21
23
  return storageData.get(_key)
@@ -32,10 +34,10 @@ describe('CloudflareWorkerVFS - Core Functionality', () => {
32
34
  },
33
35
 
34
36
  delete: (async (_key: string | string[]) => {
35
- if (Array.isArray(_key)) {
37
+ if (Array.isArray(_key) === true) {
36
38
  let count = 0
37
39
  for (const k of _key) {
38
- if (storageData.delete(k)) count++
40
+ if (storageData.delete(k) === true) count++
39
41
  }
40
42
  return count
41
43
  } else {
@@ -1,8 +1,10 @@
1
1
  /// <reference types="vitest/globals" />
2
2
 
3
+ import { beforeEach, describe, expect, it } from 'vitest'
4
+
3
5
  import type { CfTypes } from '@livestore/common-cf'
4
6
  import * as VFS from '@livestore/wa-sqlite/src/VFS.js'
5
- import { beforeEach, describe, expect, it } from 'vitest'
7
+
6
8
  import { CloudflareWorkerVFS } from '../../mod.ts'
7
9
 
8
10
  describe('CloudflareWorkerVFS - Integration Tests', () => {
@@ -17,7 +19,7 @@ describe('CloudflareWorkerVFS - Integration Tests', () => {
17
19
 
18
20
  mockStorage = {
19
21
  get: (async (_key: string | string[]) => {
20
- if (Array.isArray(_key)) {
22
+ if (Array.isArray(_key) === true) {
21
23
  storageOperations.push(`get-batch: ${_key.length} keys`)
22
24
  const result = new Map()
23
25
  for (const k of _key) {
@@ -46,11 +48,11 @@ describe('CloudflareWorkerVFS - Integration Tests', () => {
46
48
  },
47
49
 
48
50
  delete: (async (_key: string | string[]) => {
49
- if (Array.isArray(_key)) {
51
+ if (Array.isArray(_key) === true) {
50
52
  storageOperations.push(`delete-batch: ${_key.length} keys`)
51
53
  let count = 0
52
54
  for (const k of _key) {
53
- if (storageData.delete(k)) count++
55
+ if (storageData.delete(k) === true) count++
54
56
  }
55
57
  return count
56
58
  } else {
@@ -1,8 +1,10 @@
1
1
  /// <reference types="vitest/globals" />
2
2
 
3
+ import { beforeEach, describe, expect, it } from 'vitest'
4
+
3
5
  import type { CfTypes } from '@livestore/common-cf'
4
6
  import * as VFS from '@livestore/wa-sqlite/src/VFS.js'
5
- import { beforeEach, describe, expect, it } from 'vitest'
7
+
6
8
  import { CloudflareWorkerVFS } from '../../mod.ts'
7
9
 
8
10
  describe('CloudflareWorkerVFS - Reliability & Error Recovery', () => {
@@ -15,7 +17,7 @@ describe('CloudflareWorkerVFS - Reliability & Error Recovery', () => {
15
17
 
16
18
  mockStorage = {
17
19
  get: (async (_key: string | string[]) => {
18
- if (Array.isArray(_key)) {
20
+ if (Array.isArray(_key) === true) {
19
21
  return new Map()
20
22
  }
21
23
  return storageData.get(_key)
@@ -32,10 +34,10 @@ describe('CloudflareWorkerVFS - Reliability & Error Recovery', () => {
32
34
  },
33
35
 
34
36
  delete: (async (_key: string | string[]) => {
35
- if (Array.isArray(_key)) {
37
+ if (Array.isArray(_key) === true) {
36
38
  let count = 0
37
39
  for (const k of _key) {
38
- if (storageData.delete(k)) count++
40
+ if (storageData.delete(k) === true) count++
39
41
  }
40
42
  return count
41
43
  } else {