arcane-os 0.28.0 → 0.28.1

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.28.1
4
+
5
+ - DBOPFS initialization opens the application's existing storage scope without
6
+ creating product-specific table directories. Applications create the tables
7
+ they need through the existing `getTableHandle(name)` API after readiness.
8
+ - Create tables on demand and coalesce concurrent requests for the same physical
9
+ table. Logical `memories` and physical `memory` retain one shared handle and
10
+ deletion path. Existing directory discovery, complete reads and exports, CRUD,
11
+ worker fallback, events, application identity and saved data remain supported.
12
+ - Explicit `clearAllStorage()` leaves the cleared application scope empty rather
13
+ than recreating default folders. This update performs no saved-data migration
14
+ or automatic removal of existing folders. The 0.28.0 npm resource paths remain
15
+ unchanged.
16
+
3
17
  ## 0.28.0
4
18
 
5
19
  - Expose existing runtime modules and entities directly through
package/README.md CHANGED
@@ -19,7 +19,7 @@ version-locked SDK runtime, while an integrated Arcane checkout uses its live
19
19
  `arcane/` runtime. Both profiles preserve the same app URLs, theme, packaging,
20
20
  event, cancellation, and browser run contracts.
21
21
 
22
- This checkout defines the `0.28.0` SDK contract. Applications pin one exact npm
22
+ This checkout defines the `0.28.1` SDK contract. Applications pin one exact npm
23
23
  version and lockfile; registry state is deliberately not baked into application
24
24
  artifacts.
25
25
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arcane-os",
3
- "version": "0.28.0",
3
+ "version": "0.28.1",
4
4
  "description": "Arcane OS JavaScript SDK, project-local CLI, browser runtime, and repository-portable application packager.",
5
5
  "type": "module",
6
6
  "main": "./src/index.mjs",
@@ -1905,7 +1905,7 @@
1905
1905
  let tableNames=dirs;
1906
1906
 
1907
1907
  if(!tableNames?.length){
1908
- tableNames=await dbopfs.getTableNames(Boolean(layout));
1908
+ tableNames=await dbopfs.getTableNames(true);
1909
1909
  }
1910
1910
  if(destroyed||sequence!==gridLoadSequence){
1911
1911
  return [];
@@ -16,20 +16,20 @@ const dbopfsReasons={
16
16
  export const DBOPFS_EVENT_TYPES={...dbopfsEventTypes};
17
17
  export const DBOPFS_REASONS={...dbopfsReasons};
18
18
 
19
- const DEFAULT_TABLE_DIRECTORIES={
20
- users:'users',
21
- scores:'scores',
22
- chats:'chats',
23
- notes:'notes',
24
- documents:'documents',
25
- songs:'songs',
26
- images:'images',
27
- journal_entries:'journal_entries',
28
- streams_of_consciousness:'streams_of_consciousness',
29
- reports:'reports',
30
- errors:'errors',
19
+ const TABLE_DIRECTORY_ALIASES={
31
20
  memories:'memory'
32
21
  };
22
+ const DIRECTORY_TABLE_ALIASES={
23
+ memory:'memories'
24
+ };
25
+
26
+ function directoryNameForTable(tableName=''){
27
+ return TABLE_DIRECTORY_ALIASES[tableName]||tableName;
28
+ }
29
+
30
+ function tableNameForDirectory(directoryName=''){
31
+ return DIRECTORY_TABLE_ALIASES[directoryName]||directoryName;
32
+ }
33
33
 
34
34
  function parseFileValue(fileName='',textContent=''){
35
35
  let value=textContent;
@@ -79,6 +79,11 @@ if(navigator.storage?.persist){
79
79
  * Handles to directories inside OPFS.
80
80
  */
81
81
 
82
+ /**
83
+ * @typedef {Object<string,Promise<FileSystemDirectoryHandle>>} DBOPFSTableHandlePromises
84
+ * Pending table handle requests keyed by logical table name.
85
+ */
86
+
82
87
  /**
83
88
  * @typedef {Object<string,Promise>} DBOPFSWriteLocks
84
89
  * Promise based write locks to serialize writes to the same file.
@@ -119,6 +124,9 @@ class DBOPFS {
119
124
  /** @type {DBOPFSTableHandles} */
120
125
  #tableHandles={}
121
126
 
127
+ /** @type {DBOPFSTableHandlePromises} */
128
+ #tableHandlePromises={}
129
+
122
130
  /** @type {DBOPFSTables} */
123
131
  #tables={}
124
132
 
@@ -297,7 +305,7 @@ class DBOPFS {
297
305
  }
298
306
 
299
307
  /**
300
- * Initializes OPFS database and default tables.
308
+ * Initializes the application OPFS database scope.
301
309
  * Dispatches `dbopfs-ready` event when complete.
302
310
  *
303
311
  * @returns {Promise<void>}
@@ -313,7 +321,6 @@ class DBOPFS {
313
321
  this.#applicationId=scope.applicationId;
314
322
  this.#storagePath=scope.path;
315
323
  this.#db=scope.directory;
316
- await this.#createDefaultTables();
317
324
 
318
325
  this.ready=true;
319
326
 
@@ -338,15 +345,6 @@ class DBOPFS {
338
345
  projectArcaneDOMEvent(window,occurrence);
339
346
  }
340
347
 
341
- async #createDefaultTables(){
342
- for(const [alias,directoryName]of Object.entries(DEFAULT_TABLE_DIRECTORIES)){
343
- this.#tableHandles[alias]=await this.#db.getDirectoryHandle(
344
- directoryName,
345
- {create:true}
346
- );
347
- }
348
- }
349
-
350
348
  /**
351
349
  * Canonical application identity owning this database.
352
350
  *
@@ -403,19 +401,49 @@ class DBOPFS {
403
401
  await this.readyPromise;
404
402
  }
405
403
 
406
- if(!this.#tableHandles[tableName]){
407
- const existingHandle=Object.values(this.#tableHandles).find(
408
- handle=>handle.name===tableName
409
- )
404
+ const directoryName=directoryNameForTable(tableName);
405
+ const registeredTableName=tableNameForDirectory(directoryName);
410
406
 
411
- if(existingHandle){
412
- return existingHandle
407
+ if(this.#tableHandles[registeredTableName]){
408
+ return this.#tableHandles[registeredTableName];
409
+ }
410
+
411
+ const existingHandle=Object.values(this.#tableHandles).find(
412
+ function matchingTableDirectory(handle){
413
+ return handle.name===directoryName;
413
414
  }
415
+ );
414
416
 
415
- this.#tableHandles[tableName]=await this.#db.getDirectoryHandle(tableName,{create:true});
417
+ if(existingHandle){
418
+ this.#tableHandles[registeredTableName]=existingHandle;
419
+ return existingHandle;
416
420
  }
417
421
 
418
- return this.#tableHandles[tableName];
422
+ if(!this.#tableHandlePromises[registeredTableName]){
423
+ const handlePromise=this.#db.getDirectoryHandle(
424
+ directoryName,
425
+ {create:true}
426
+ ).then(
427
+ function registerRequestedTable(handle){
428
+ this.#tableHandles[registeredTableName]=handle;
429
+ return handle;
430
+ }.bind(this)
431
+ );
432
+ this.#tableHandlePromises[registeredTableName]=handlePromise;
433
+
434
+ function clearTableHandlePromise(){
435
+ if(this.#tableHandlePromises[registeredTableName]===handlePromise){
436
+ delete this.#tableHandlePromises[registeredTableName];
437
+ }
438
+ }
439
+
440
+ handlePromise.then(
441
+ clearTableHandlePromise.bind(this),
442
+ clearTableHandlePromise.bind(this)
443
+ );
444
+ }
445
+
446
+ return this.#tableHandlePromises[registeredTableName];
419
447
  }
420
448
 
421
449
  /**
@@ -779,11 +807,17 @@ class DBOPFS {
779
807
  * @returns {Promise<boolean>}
780
808
  */
781
809
  async deleteTable(tableName){
810
+ const directoryName=directoryNameForTable(tableName);
811
+ const registeredTableName=tableNameForDirectory(directoryName);
812
+
782
813
  try{
783
- await this.#db.removeEntry(tableName,{recursive:true})
814
+ await this.#db.removeEntry(directoryName,{recursive:true})
784
815
 
785
816
  delete this.#tables[tableName]
786
- delete this.#tableHandles[tableName]
817
+ delete this.#tables[directoryName]
818
+ delete this.#tables[registeredTableName]
819
+ delete this.#tableHandles[registeredTableName]
820
+ delete this.#tableHandlePromises[registeredTableName]
787
821
  }catch(error){
788
822
  arcaneLogging.error(error)
789
823
  }
@@ -807,8 +841,8 @@ class DBOPFS {
807
841
 
808
842
  this.#tables={}
809
843
  this.#tableHandles={}
844
+ this.#tableHandlePromises={}
810
845
  this.#writeLocks={}
811
- await this.#createDefaultTables()
812
846
 
813
847
  return this
814
848
  }
@@ -864,12 +898,15 @@ class DBOPFS {
864
898
  continue
865
899
  }
866
900
 
901
+ const registeredTableName=tableNameForDirectory(name);
867
902
  const registered=Object.values(this.#tableHandles).some(
868
- tableHandle=>tableHandle.name===name
869
- )
903
+ function matchingDiscoveredDirectory(tableHandle){
904
+ return tableHandle.name===name;
905
+ }
906
+ );
870
907
 
871
908
  if(!registered){
872
- this.#tableHandles[name]=handle
909
+ this.#tableHandles[registeredTableName]=handle
873
910
  }
874
911
 
875
912
  tableNames.push(name)