braid-text 0.2.75 → 0.2.77

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.
@@ -4,7 +4,9 @@
4
4
  "Bash(node test/test.js:*)",
5
5
  "Bash(node:*)",
6
6
  "Bash(git add:*)",
7
- "Bash(git commit -m \"$(cat <<''EOF''\n0.2.74 - updates url-file-db to 0.0.19\n\nšŸ¤– Generated with [Claude Code](https://claude.com/claude-code)\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nEOF\n)\")"
7
+ "Bash(git commit -m \"$(cat <<''EOF''\n0.2.74 - updates url-file-db to 0.0.19\n\nšŸ¤– Generated with [Claude Code](https://claude.com/claude-code)\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nEOF\n)\")",
8
+ "Bash(git push)",
9
+ "Bash(npm publish:*)"
8
10
  ],
9
11
  "deny": [],
10
12
  "ask": []
package/index.js CHANGED
@@ -463,8 +463,30 @@ function create_braid_text() {
463
463
  throw new Error("unknown")
464
464
  }
465
465
 
466
- braid_text.delete = async (key) => {
467
- await braid_text.put(key, {body: ''})
466
+ braid_text.delete = async (key, options) => {
467
+ if (!options) options = {}
468
+
469
+ // Handle URL - make a DELETE request
470
+ if (key instanceof URL) {
471
+ options.my_abort = new AbortController()
472
+ if (options.signal)
473
+ options.signal.addEventListener('abort', () =>
474
+ options.my_abort.abort())
475
+
476
+ var params = {
477
+ method: 'DELETE',
478
+ signal: options.my_abort.signal,
479
+ retry: () => true,
480
+ }
481
+ for (var x of ['headers', 'peer'])
482
+ if (options[x] != null) params[x] = options[x]
483
+
484
+ return await braid_fetch(key.href, params)
485
+ }
486
+
487
+ // Accept either a key string or a resource object
488
+ let resource = (typeof key == 'string') ? await get_resource(key) : key
489
+ await resource.delete()
468
490
  }
469
491
 
470
492
  braid_text.get = async (key, options) => {
@@ -1029,6 +1051,42 @@ function create_braid_text() {
1029
1051
 
1030
1052
  resource.length_cache = createSimpleCache(braid_text.length_cache_size)
1031
1053
 
1054
+ // Add delete method to resource
1055
+ resource.delete = async () => {
1056
+ // Free the diamond-types document
1057
+ if (resource.doc) resource.doc.free()
1058
+
1059
+ // Remove from in-memory cache
1060
+ delete braid_text.cache[key]
1061
+
1062
+ // Remove all files for this key from db_folder
1063
+ if (braid_text.db_folder) {
1064
+ var files = await get_files_for_key(key)
1065
+ for (var file of files) {
1066
+ try {
1067
+ await fs.promises.unlink(file)
1068
+ } catch (e) {
1069
+ // File might not exist, that's ok
1070
+ }
1071
+ }
1072
+
1073
+ // Remove meta file if it exists
1074
+ try {
1075
+ var encoded = encode_filename(key)
1076
+ await fs.promises.unlink(`${braid_text.db_folder}/.meta/${encoded}`)
1077
+ } catch (e) {
1078
+ // Meta file might not exist, that's ok
1079
+ }
1080
+ }
1081
+
1082
+ // Remove from filename mapping
1083
+ if (key_to_filename.has(key)) {
1084
+ var encoded = key_to_filename.get(key)
1085
+ ifilenames.delete(encoded.toLowerCase())
1086
+ key_to_filename.delete(key)
1087
+ }
1088
+ }
1089
+
1032
1090
  done(resource)
1033
1091
  })
1034
1092
  return await cache[key]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "braid-text",
3
- "version": "0.2.75",
3
+ "version": "0.2.77",
4
4
  "description": "Library for collaborative text over http using braid.",
5
5
  "author": "Braid Working Group",
6
6
  "repository": "braid-org/braid-text",
package/test/tests.js CHANGED
@@ -1840,6 +1840,95 @@ runTest(
1840
1840
  ''
1841
1841
  )
1842
1842
 
1843
+ runTest(
1844
+ "test deleting a resource completely removes all traces",
1845
+ async () => {
1846
+ let key = 'test-delete-complete-' + Math.random().toString(36).slice(2)
1847
+
1848
+ // Create a resource with some content
1849
+ // "hello world" is 11 characters, so version should be alice-10 (positions 0-10 inclusive)
1850
+ await braid_fetch(`/${key}`, {
1851
+ method: 'PUT',
1852
+ version: ['alice-10'],
1853
+ parents: [],
1854
+ body: 'hello world'
1855
+ })
1856
+
1857
+ // Verify it exists in cache using eval endpoint
1858
+ let r1 = await braid_fetch(`/eval`, {
1859
+ method: 'PUT',
1860
+ body: `res.end(braid_text.cache['/${key}'] ? 'exists' : 'missing')`
1861
+ })
1862
+ if ((await r1.text()) !== 'exists') return 'Resource not in cache after creation'
1863
+
1864
+ // Delete the resource
1865
+ await braid_fetch(`/${key}`, {method: 'DELETE'})
1866
+
1867
+ // Verify it's removed from cache
1868
+ let r2 = await braid_fetch(`/eval`, {
1869
+ method: 'PUT',
1870
+ body: `res.end(braid_text.cache['/${key}'] ? 'exists' : 'missing')`
1871
+ })
1872
+ if ((await r2.text()) !== 'missing') return 'Resource still in cache after deletion'
1873
+
1874
+ // Verify we can create it again from scratch with same key
1875
+ // "new content" is 11 characters, so version should be bob-10 (positions 0-10 inclusive)
1876
+ await braid_fetch(`/${key}`, {
1877
+ method: 'PUT',
1878
+ version: ['bob-10'],
1879
+ parents: [],
1880
+ body: 'new content'
1881
+ })
1882
+
1883
+ // Get the new resource and verify it's fresh (not the old one)
1884
+ let r = await braid_fetch(`/${key}`)
1885
+ let body = await r.text()
1886
+
1887
+ if (body !== 'new content') return `Expected 'new content', got '${body}'`
1888
+
1889
+ // Verify the version is from scratch (bob-10, not alice-10)
1890
+ let version = r.headers.get('version')
1891
+ if (!version.includes('bob-10')) return `Expected version to include bob-10, got: ${version}`
1892
+ if (version.includes('alice-')) return `Old version alice-10 should not be present, got: ${version}`
1893
+
1894
+ return 'ok'
1895
+ },
1896
+ 'ok'
1897
+ )
1898
+
1899
+ runTest(
1900
+ "test braid_text.delete(url)",
1901
+ async () => {
1902
+ var key = 'test-' + Math.random().toString(36).slice(2)
1903
+
1904
+ // Create a resource first
1905
+ await braid_fetch(`/${key}`, {
1906
+ method: 'PUT',
1907
+ body: 'hello there'
1908
+ })
1909
+
1910
+ // Verify it exists
1911
+ let r1 = await braid_fetch(`/${key}`)
1912
+ if ((await r1.text()) !== 'hello there') return 'Resource not created properly'
1913
+
1914
+ // Delete using braid_text.delete(url)
1915
+ var r = await braid_fetch(`/eval`, {
1916
+ method: 'PUT',
1917
+ body: `void (async () => {
1918
+ await braid_text.delete(new URL('http://localhost:8889/${key}'))
1919
+ res.end('deleted')
1920
+ })()`
1921
+ })
1922
+ if (!r.ok) return 'delete failed: ' + r.status
1923
+ if ((await r.text()) !== 'deleted') return 'delete did not complete'
1924
+
1925
+ // Verify it's deleted (should be empty)
1926
+ let r2 = await braid_fetch(`/${key}`)
1927
+ return 'got: ' + (await r2.text())
1928
+ },
1929
+ 'got: '
1930
+ )
1931
+
1843
1932
  runTest(
1844
1933
  "test getting a binary update from a subscription",
1845
1934
  async () => {