js-bao 0.3.0-alpha.0 → 0.3.0-alpha.2

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.
@@ -1979,6 +1979,7 @@ function createDatabaseDO(config = {}) {
1979
1979
  if (request.method === "DELETE" && path === "/destroy") {
1980
1980
  await this._doState.storage.deleteAll();
1981
1981
  this._initialized = false;
1982
+ this._engine.initialized = false;
1982
1983
  return Response.json({
1983
1984
  deleted: true,
1984
1985
  deletedAt: (/* @__PURE__ */ new Date()).toISOString()
@@ -2026,6 +2027,8 @@ function createDatabaseDO(config = {}) {
2026
2027
  return this._handleHealth();
2027
2028
  case "/describe":
2028
2029
  return this._handleDescribe(request);
2030
+ case "/models":
2031
+ return this._handleModelList();
2029
2032
  default:
2030
2033
  return this._errorResponse("Not found", 404);
2031
2034
  }
@@ -2047,6 +2050,7 @@ function createDatabaseDO(config = {}) {
2047
2050
  modelName,
2048
2051
  docId,
2049
2052
  request,
2053
+ engine: this._engine,
2050
2054
  filter,
2051
2055
  options
2052
2056
  };
@@ -2065,7 +2069,18 @@ function createDatabaseDO(config = {}) {
2065
2069
  });
2066
2070
  const { sql, params, sortFields } = translator.translateFind(filter, options);
2067
2071
  const rawResults = this._engine.execSqlSync(sql, params);
2068
- const data = rawResults.map((row) => this._parseRow(row));
2072
+ let data = rawResults.map((row) => this._parseRow(row));
2073
+ if (hooks?.afterQuery) {
2074
+ const ctx = {
2075
+ modelName,
2076
+ docId,
2077
+ request,
2078
+ engine: this._engine,
2079
+ results: data
2080
+ };
2081
+ const result = await hooks.afterQuery(ctx);
2082
+ data = result.results;
2083
+ }
2069
2084
  const limit = options?.limit;
2070
2085
  const hasMore = CursorManager.hasMoreResults(limit, data.length);
2071
2086
  const isFirstPage = !options?.uniqueStartKey;
@@ -2083,6 +2098,18 @@ function createDatabaseDO(config = {}) {
2083
2098
  };
2084
2099
  return Response.json(response);
2085
2100
  }
2101
+ /** @internal — Check for reserved field names in record data */
2102
+ _checkReservedFields(data) {
2103
+ for (const key of Object.keys(data)) {
2104
+ if (key === "type") {
2105
+ return `Field 'type' is reserved and cannot be used in record data`;
2106
+ }
2107
+ if (key.startsWith("_meta")) {
2108
+ return `Field '${key}' is reserved (fields starting with '_meta' are internal) and cannot be used in record data`;
2109
+ }
2110
+ }
2111
+ return null;
2112
+ }
2086
2113
  /** @internal */
2087
2114
  async _handleSave(request, docId) {
2088
2115
  const body = await request.json();
@@ -2090,6 +2117,15 @@ function createDatabaseDO(config = {}) {
2090
2117
  if (!modelName || !id) {
2091
2118
  return this._errorResponse("modelName and id are required", 400);
2092
2119
  }
2120
+ if (!data) {
2121
+ return this._errorResponse("data is required", 400);
2122
+ }
2123
+ if (data) {
2124
+ const reservedError = this._checkReservedFields(data);
2125
+ if (reservedError) {
2126
+ return this._errorResponse(reservedError, 400);
2127
+ }
2128
+ }
2093
2129
  if (condition && !this._checkCondition(modelName, id, condition)) {
2094
2130
  return this._errorResponse(
2095
2131
  `Condition not met for ${modelName}/${id}`,
@@ -2108,6 +2144,7 @@ function createDatabaseDO(config = {}) {
2108
2144
  modelName,
2109
2145
  docId,
2110
2146
  request,
2147
+ engine: this._engine,
2111
2148
  id,
2112
2149
  data,
2113
2150
  stringSets,
@@ -2146,6 +2183,10 @@ function createDatabaseDO(config = {}) {
2146
2183
  if (!modelName || !id || !data) {
2147
2184
  return this._errorResponse("modelName, id, and data are required", 400);
2148
2185
  }
2186
+ const reservedError = this._checkReservedFields(data);
2187
+ if (reservedError) {
2188
+ return this._errorResponse(reservedError, 400);
2189
+ }
2149
2190
  if (!this._engine.recordExists(modelName, id)) {
2150
2191
  return this._errorResponse(`Record ${modelName}/${id} not found`, 404);
2151
2192
  }
@@ -2160,6 +2201,7 @@ function createDatabaseDO(config = {}) {
2160
2201
  modelName,
2161
2202
  docId,
2162
2203
  request,
2204
+ engine: this._engine,
2163
2205
  id,
2164
2206
  data,
2165
2207
  stringSets,
@@ -2205,11 +2247,21 @@ function createDatabaseDO(config = {}) {
2205
2247
  );
2206
2248
  }
2207
2249
  if (hooks?.beforeDelete) {
2250
+ let record = null;
2251
+ const rows = this._engine.execSqlSync(
2252
+ "SELECT id, type, data_json FROM records WHERE id = ? AND type = ?",
2253
+ [id, modelName]
2254
+ );
2255
+ if (rows.length > 0) {
2256
+ record = this._parseRow(rows[0]);
2257
+ }
2208
2258
  const ctx = {
2209
2259
  modelName,
2210
2260
  docId,
2211
2261
  request,
2212
- id
2262
+ engine: this._engine,
2263
+ id,
2264
+ record
2213
2265
  };
2214
2266
  const result = await hooks.beforeDelete(ctx);
2215
2267
  if (!result.allow) {
@@ -2243,12 +2295,20 @@ function createDatabaseDO(config = {}) {
2243
2295
  400
2244
2296
  );
2245
2297
  }
2298
+ const reservedError = this._checkReservedFields(op.data);
2299
+ if (reservedError) {
2300
+ return this._errorResponse(
2301
+ `Operation ${i}: ${reservedError}`,
2302
+ 400
2303
+ );
2304
+ }
2246
2305
  if (hooks?.beforeSave) {
2247
2306
  const isNew = op.op === "save" ? !this._engine.recordExists(op.modelName, op.id) : false;
2248
2307
  const ctx = {
2249
2308
  modelName: op.modelName,
2250
2309
  docId,
2251
2310
  request,
2311
+ engine: this._engine,
2252
2312
  id: op.id,
2253
2313
  data: op.data,
2254
2314
  stringSets: op.stringSets,
@@ -2261,11 +2321,21 @@ function createDatabaseDO(config = {}) {
2261
2321
  }
2262
2322
  } else if (op.op === "delete") {
2263
2323
  if (hooks?.beforeDelete) {
2324
+ let record = null;
2325
+ const rows = this._engine.execSqlSync(
2326
+ "SELECT id, type, data_json FROM records WHERE id = ? AND type = ?",
2327
+ [op.id, op.modelName]
2328
+ );
2329
+ if (rows.length > 0) {
2330
+ record = this._parseRow(rows[0]);
2331
+ }
2264
2332
  const ctx = {
2265
2333
  modelName: op.modelName,
2266
2334
  docId,
2267
2335
  request,
2268
- id: op.id
2336
+ engine: this._engine,
2337
+ id: op.id,
2338
+ record
2269
2339
  };
2270
2340
  const result = await hooks.beforeDelete(ctx);
2271
2341
  if (!result.allow) {
@@ -2490,6 +2560,7 @@ function createDatabaseDO(config = {}) {
2490
2560
  modelName,
2491
2561
  docId,
2492
2562
  request,
2563
+ engine: this._engine,
2493
2564
  filter
2494
2565
  };
2495
2566
  const result = await hooks.beforeQuery(ctx);
@@ -2602,6 +2673,7 @@ function createDatabaseDO(config = {}) {
2602
2673
  modelName,
2603
2674
  docId,
2604
2675
  request,
2676
+ engine: this._engine,
2605
2677
  filter
2606
2678
  };
2607
2679
  const result = await hooks.beforeQuery(ctx);
@@ -3087,6 +3159,23 @@ function createDatabaseDO(config = {}) {
3087
3159
  const response = { modelName, fields };
3088
3160
  return Response.json(response);
3089
3161
  }
3162
+ /** @internal — List all known model names from records and _model_fields */
3163
+ _handleModelList() {
3164
+ const fromRecords = this._engine.execSqlSync(
3165
+ "SELECT DISTINCT type FROM records ORDER BY type"
3166
+ );
3167
+ const fromFields = this._engine.execSqlSync(
3168
+ "SELECT DISTINCT model_name FROM _model_fields ORDER BY model_name"
3169
+ );
3170
+ const fromIndexes = this._engine.execSqlSync(
3171
+ "SELECT DISTINCT model_name FROM _indexes ORDER BY model_name"
3172
+ );
3173
+ const modelSet = /* @__PURE__ */ new Set();
3174
+ for (const row of fromRecords) modelSet.add(row.type);
3175
+ for (const row of fromFields) modelSet.add(row.model_name);
3176
+ for (const row of fromIndexes) modelSet.add(row.model_name);
3177
+ return Response.json({ models: Array.from(modelSet).sort() });
3178
+ }
3090
3179
  /** @internal */
3091
3180
  _errorResponse(message, status) {
3092
3181
  const body = { error: message };
@@ -194,7 +194,7 @@ interface JsonSchemaEngineOptions extends JsonSchemaOptions {
194
194
  }
195
195
  declare abstract class JsonSchemaEngine extends DatabaseEngine {
196
196
  protected schemaOptions: JsonSchemaEngineOptions;
197
- protected initialized: boolean;
197
+ initialized: boolean;
198
198
  constructor(options: JsonSchemaEngineOptions);
199
199
  /**
200
200
  * Execute SQL and return results.
@@ -880,6 +880,8 @@ interface HookContext {
880
880
  docId: string;
881
881
  /** The raw request (for reading headers, auth tokens, etc.) */
882
882
  request: Request;
883
+ /** The DO's SQLite engine (for direct queries, e.g. lookup functions) */
884
+ engine: any;
883
885
  }
884
886
  /** Context for beforeSave hooks */
885
887
  interface BeforeSaveContext extends HookContext {
@@ -896,6 +898,8 @@ interface BeforeSaveContext extends HookContext {
896
898
  interface BeforeDeleteContext extends HookContext {
897
899
  /** Record ID being deleted */
898
900
  id: string;
901
+ /** The existing record being deleted (parsed from data_json) */
902
+ record: Record<string, any> | null;
899
903
  }
900
904
  /** Context for beforeQuery hooks */
901
905
  interface BeforeQueryContext extends HookContext {
@@ -904,6 +908,11 @@ interface BeforeQueryContext extends HookContext {
904
908
  /** Query options (sort, limit, etc.) */
905
909
  options?: QueryOptions;
906
910
  }
911
+ /** Context for afterQuery hooks */
912
+ interface AfterQueryContext extends HookContext {
913
+ /** The query results to filter */
914
+ results: Record<string, any>[];
915
+ }
907
916
  /** Result from beforeSave/beforeDelete hooks */
908
917
  interface HookResult {
909
918
  allow: boolean;
@@ -915,11 +924,17 @@ interface BeforeQueryResult extends HookResult {
915
924
  /** Additional filter merged into the query via $and */
916
925
  injectFilter?: DocumentFilter;
917
926
  }
927
+ /** Result from afterQuery hooks — returns filtered results */
928
+ interface AfterQueryResult {
929
+ /** The filtered results to return */
930
+ results: Record<string, any>[];
931
+ }
918
932
  /** Hook definitions for createDatabaseDO */
919
933
  interface DatabaseDOHooks {
920
934
  beforeSave?: (ctx: BeforeSaveContext) => Promise<HookResult>;
921
935
  beforeDelete?: (ctx: BeforeDeleteContext) => Promise<HookResult>;
922
936
  beforeQuery?: (ctx: BeforeQueryContext) => Promise<BeforeQueryResult>;
937
+ afterQuery?: (ctx: AfterQueryContext) => Promise<AfterQueryResult>;
923
938
  }
924
939
 
925
940
  /**
@@ -1151,6 +1166,8 @@ declare function createDatabaseDO(config?: DatabaseDOConfig): {
1151
1166
  fetch(request: Request): Promise<Response>;
1152
1167
  /** @internal */
1153
1168
  _handleQuery(request: Request, docId: string): Promise<Response>;
1169
+ /** @internal — Check for reserved field names in record data */
1170
+ _checkReservedFields(data: Record<string, any>): string | null;
1154
1171
  /** @internal */
1155
1172
  _handleSave(request: Request, docId: string): Promise<Response>;
1156
1173
  /** @internal — Partial update: merge provided fields into existing record */
@@ -1231,6 +1248,8 @@ declare function createDatabaseDO(config?: DatabaseDOConfig): {
1231
1248
  _handleHealth(): Response;
1232
1249
  /** @internal — Return tracked field names and types for a model */
1233
1250
  _handleDescribe(request: Request): Response;
1251
+ /** @internal — List all known model names from records and _model_fields */
1252
+ _handleModelList(): Response;
1234
1253
  /** @internal */
1235
1254
  _errorResponse(message: string, status: number): Response;
1236
1255
  /** @internal */
@@ -1300,4 +1319,4 @@ interface Env {
1300
1319
  */
1301
1320
  declare function handleRequest(request: Request, env: Env): Promise<Response>;
1302
1321
 
1303
- export { type AggregateRequest, type AggregateResponse, type AggregationOperation, type AggregationOptions, type AggregationResult, type BatchOperation, type BatchOperationResult, type BatchRequest, type BatchResponse, type BeforeDeleteContext, type BeforeQueryContext, type BeforeQueryResult, type BeforeSaveContext, type CountRequest, type CountResponse, type DatabaseDOConfig, type DatabaseDOHooks, type DeleteRequest, type DeleteResponse, type DocumentDOConfig, type DropIndexRequest, type DropIndexResponse, type DropUniqueConstraintRequest, type DropUniqueConstraintResponse, DurableObjectEngine, type DurableObjectEngineOptions, type DurableObjectId, type DurableObjectNamespace, type DurableObjectState, type DurableObjectStorage, type DurableObjectStub, type Env, type ErrorResponse, type GroupByField, type HookContext, type HookResult, type IncrementRequest, type IncrementResponse, type IndexEntry, type IndexListResponse, JsonQueryTranslator, type JsonQueryTranslatorOptions, JsonSchemaDDL, type JsonSchemaOptions, type PatchRequest, type PatchResponse, type QueryRequest, type QueryResponse, type RegisterIndexRequest, type RegisterIndexResponse, type RegisterUniqueConstraintRequest, type RegisterUniqueConstraintResponse, type SaveRequest, type SaveResponse, type SqlStorage, type SqlStorageCursor, type StringSetMembership, type StringSetUpdateRequest, type StringSetUpdateResponse, type SyncIndexesRequest, type SyncIndexesResponse, type UniqueConstraintEntry, type UniqueConstraintListResponse, createDatabaseDO, createDocumentDO, handleRequest };
1322
+ export { type AfterQueryContext, type AfterQueryResult, type AggregateRequest, type AggregateResponse, type AggregationOperation, type AggregationOptions, type AggregationResult, type BatchOperation, type BatchOperationResult, type BatchRequest, type BatchResponse, type BeforeDeleteContext, type BeforeQueryContext, type BeforeQueryResult, type BeforeSaveContext, type CountRequest, type CountResponse, type DatabaseDOConfig, type DatabaseDOHooks, type DeleteRequest, type DeleteResponse, type DocumentDOConfig, type DropIndexRequest, type DropIndexResponse, type DropUniqueConstraintRequest, type DropUniqueConstraintResponse, DurableObjectEngine, type DurableObjectEngineOptions, type DurableObjectId, type DurableObjectNamespace, type DurableObjectState, type DurableObjectStorage, type DurableObjectStub, type Env, type ErrorResponse, type GroupByField, type HookContext, type HookResult, type IncrementRequest, type IncrementResponse, type IndexEntry, type IndexListResponse, JsonQueryTranslator, type JsonQueryTranslatorOptions, JsonSchemaDDL, type JsonSchemaOptions, type PatchRequest, type PatchResponse, type QueryRequest, type QueryResponse, type RegisterIndexRequest, type RegisterIndexResponse, type RegisterUniqueConstraintRequest, type RegisterUniqueConstraintResponse, type SaveRequest, type SaveResponse, type SqlStorage, type SqlStorageCursor, type StringSetMembership, type StringSetUpdateRequest, type StringSetUpdateResponse, type SyncIndexesRequest, type SyncIndexesResponse, type UniqueConstraintEntry, type UniqueConstraintListResponse, createDatabaseDO, createDocumentDO, handleRequest };
@@ -194,7 +194,7 @@ interface JsonSchemaEngineOptions extends JsonSchemaOptions {
194
194
  }
195
195
  declare abstract class JsonSchemaEngine extends DatabaseEngine {
196
196
  protected schemaOptions: JsonSchemaEngineOptions;
197
- protected initialized: boolean;
197
+ initialized: boolean;
198
198
  constructor(options: JsonSchemaEngineOptions);
199
199
  /**
200
200
  * Execute SQL and return results.
@@ -880,6 +880,8 @@ interface HookContext {
880
880
  docId: string;
881
881
  /** The raw request (for reading headers, auth tokens, etc.) */
882
882
  request: Request;
883
+ /** The DO's SQLite engine (for direct queries, e.g. lookup functions) */
884
+ engine: any;
883
885
  }
884
886
  /** Context for beforeSave hooks */
885
887
  interface BeforeSaveContext extends HookContext {
@@ -896,6 +898,8 @@ interface BeforeSaveContext extends HookContext {
896
898
  interface BeforeDeleteContext extends HookContext {
897
899
  /** Record ID being deleted */
898
900
  id: string;
901
+ /** The existing record being deleted (parsed from data_json) */
902
+ record: Record<string, any> | null;
899
903
  }
900
904
  /** Context for beforeQuery hooks */
901
905
  interface BeforeQueryContext extends HookContext {
@@ -904,6 +908,11 @@ interface BeforeQueryContext extends HookContext {
904
908
  /** Query options (sort, limit, etc.) */
905
909
  options?: QueryOptions;
906
910
  }
911
+ /** Context for afterQuery hooks */
912
+ interface AfterQueryContext extends HookContext {
913
+ /** The query results to filter */
914
+ results: Record<string, any>[];
915
+ }
907
916
  /** Result from beforeSave/beforeDelete hooks */
908
917
  interface HookResult {
909
918
  allow: boolean;
@@ -915,11 +924,17 @@ interface BeforeQueryResult extends HookResult {
915
924
  /** Additional filter merged into the query via $and */
916
925
  injectFilter?: DocumentFilter;
917
926
  }
927
+ /** Result from afterQuery hooks — returns filtered results */
928
+ interface AfterQueryResult {
929
+ /** The filtered results to return */
930
+ results: Record<string, any>[];
931
+ }
918
932
  /** Hook definitions for createDatabaseDO */
919
933
  interface DatabaseDOHooks {
920
934
  beforeSave?: (ctx: BeforeSaveContext) => Promise<HookResult>;
921
935
  beforeDelete?: (ctx: BeforeDeleteContext) => Promise<HookResult>;
922
936
  beforeQuery?: (ctx: BeforeQueryContext) => Promise<BeforeQueryResult>;
937
+ afterQuery?: (ctx: AfterQueryContext) => Promise<AfterQueryResult>;
923
938
  }
924
939
 
925
940
  /**
@@ -1151,6 +1166,8 @@ declare function createDatabaseDO(config?: DatabaseDOConfig): {
1151
1166
  fetch(request: Request): Promise<Response>;
1152
1167
  /** @internal */
1153
1168
  _handleQuery(request: Request, docId: string): Promise<Response>;
1169
+ /** @internal — Check for reserved field names in record data */
1170
+ _checkReservedFields(data: Record<string, any>): string | null;
1154
1171
  /** @internal */
1155
1172
  _handleSave(request: Request, docId: string): Promise<Response>;
1156
1173
  /** @internal — Partial update: merge provided fields into existing record */
@@ -1231,6 +1248,8 @@ declare function createDatabaseDO(config?: DatabaseDOConfig): {
1231
1248
  _handleHealth(): Response;
1232
1249
  /** @internal — Return tracked field names and types for a model */
1233
1250
  _handleDescribe(request: Request): Response;
1251
+ /** @internal — List all known model names from records and _model_fields */
1252
+ _handleModelList(): Response;
1234
1253
  /** @internal */
1235
1254
  _errorResponse(message: string, status: number): Response;
1236
1255
  /** @internal */
@@ -1300,4 +1319,4 @@ interface Env {
1300
1319
  */
1301
1320
  declare function handleRequest(request: Request, env: Env): Promise<Response>;
1302
1321
 
1303
- export { type AggregateRequest, type AggregateResponse, type AggregationOperation, type AggregationOptions, type AggregationResult, type BatchOperation, type BatchOperationResult, type BatchRequest, type BatchResponse, type BeforeDeleteContext, type BeforeQueryContext, type BeforeQueryResult, type BeforeSaveContext, type CountRequest, type CountResponse, type DatabaseDOConfig, type DatabaseDOHooks, type DeleteRequest, type DeleteResponse, type DocumentDOConfig, type DropIndexRequest, type DropIndexResponse, type DropUniqueConstraintRequest, type DropUniqueConstraintResponse, DurableObjectEngine, type DurableObjectEngineOptions, type DurableObjectId, type DurableObjectNamespace, type DurableObjectState, type DurableObjectStorage, type DurableObjectStub, type Env, type ErrorResponse, type GroupByField, type HookContext, type HookResult, type IncrementRequest, type IncrementResponse, type IndexEntry, type IndexListResponse, JsonQueryTranslator, type JsonQueryTranslatorOptions, JsonSchemaDDL, type JsonSchemaOptions, type PatchRequest, type PatchResponse, type QueryRequest, type QueryResponse, type RegisterIndexRequest, type RegisterIndexResponse, type RegisterUniqueConstraintRequest, type RegisterUniqueConstraintResponse, type SaveRequest, type SaveResponse, type SqlStorage, type SqlStorageCursor, type StringSetMembership, type StringSetUpdateRequest, type StringSetUpdateResponse, type SyncIndexesRequest, type SyncIndexesResponse, type UniqueConstraintEntry, type UniqueConstraintListResponse, createDatabaseDO, createDocumentDO, handleRequest };
1322
+ export { type AfterQueryContext, type AfterQueryResult, type AggregateRequest, type AggregateResponse, type AggregationOperation, type AggregationOptions, type AggregationResult, type BatchOperation, type BatchOperationResult, type BatchRequest, type BatchResponse, type BeforeDeleteContext, type BeforeQueryContext, type BeforeQueryResult, type BeforeSaveContext, type CountRequest, type CountResponse, type DatabaseDOConfig, type DatabaseDOHooks, type DeleteRequest, type DeleteResponse, type DocumentDOConfig, type DropIndexRequest, type DropIndexResponse, type DropUniqueConstraintRequest, type DropUniqueConstraintResponse, DurableObjectEngine, type DurableObjectEngineOptions, type DurableObjectId, type DurableObjectNamespace, type DurableObjectState, type DurableObjectStorage, type DurableObjectStub, type Env, type ErrorResponse, type GroupByField, type HookContext, type HookResult, type IncrementRequest, type IncrementResponse, type IndexEntry, type IndexListResponse, JsonQueryTranslator, type JsonQueryTranslatorOptions, JsonSchemaDDL, type JsonSchemaOptions, type PatchRequest, type PatchResponse, type QueryRequest, type QueryResponse, type RegisterIndexRequest, type RegisterIndexResponse, type RegisterUniqueConstraintRequest, type RegisterUniqueConstraintResponse, type SaveRequest, type SaveResponse, type SqlStorage, type SqlStorageCursor, type StringSetMembership, type StringSetUpdateRequest, type StringSetUpdateResponse, type SyncIndexesRequest, type SyncIndexesResponse, type UniqueConstraintEntry, type UniqueConstraintListResponse, createDatabaseDO, createDocumentDO, handleRequest };
@@ -1948,6 +1948,7 @@ function createDatabaseDO(config = {}) {
1948
1948
  if (request.method === "DELETE" && path === "/destroy") {
1949
1949
  await this._doState.storage.deleteAll();
1950
1950
  this._initialized = false;
1951
+ this._engine.initialized = false;
1951
1952
  return Response.json({
1952
1953
  deleted: true,
1953
1954
  deletedAt: (/* @__PURE__ */ new Date()).toISOString()
@@ -1995,6 +1996,8 @@ function createDatabaseDO(config = {}) {
1995
1996
  return this._handleHealth();
1996
1997
  case "/describe":
1997
1998
  return this._handleDescribe(request);
1999
+ case "/models":
2000
+ return this._handleModelList();
1998
2001
  default:
1999
2002
  return this._errorResponse("Not found", 404);
2000
2003
  }
@@ -2016,6 +2019,7 @@ function createDatabaseDO(config = {}) {
2016
2019
  modelName,
2017
2020
  docId,
2018
2021
  request,
2022
+ engine: this._engine,
2019
2023
  filter,
2020
2024
  options
2021
2025
  };
@@ -2034,7 +2038,18 @@ function createDatabaseDO(config = {}) {
2034
2038
  });
2035
2039
  const { sql, params, sortFields } = translator.translateFind(filter, options);
2036
2040
  const rawResults = this._engine.execSqlSync(sql, params);
2037
- const data = rawResults.map((row) => this._parseRow(row));
2041
+ let data = rawResults.map((row) => this._parseRow(row));
2042
+ if (hooks?.afterQuery) {
2043
+ const ctx = {
2044
+ modelName,
2045
+ docId,
2046
+ request,
2047
+ engine: this._engine,
2048
+ results: data
2049
+ };
2050
+ const result = await hooks.afterQuery(ctx);
2051
+ data = result.results;
2052
+ }
2038
2053
  const limit = options?.limit;
2039
2054
  const hasMore = CursorManager.hasMoreResults(limit, data.length);
2040
2055
  const isFirstPage = !options?.uniqueStartKey;
@@ -2052,6 +2067,18 @@ function createDatabaseDO(config = {}) {
2052
2067
  };
2053
2068
  return Response.json(response);
2054
2069
  }
2070
+ /** @internal — Check for reserved field names in record data */
2071
+ _checkReservedFields(data) {
2072
+ for (const key of Object.keys(data)) {
2073
+ if (key === "type") {
2074
+ return `Field 'type' is reserved and cannot be used in record data`;
2075
+ }
2076
+ if (key.startsWith("_meta")) {
2077
+ return `Field '${key}' is reserved (fields starting with '_meta' are internal) and cannot be used in record data`;
2078
+ }
2079
+ }
2080
+ return null;
2081
+ }
2055
2082
  /** @internal */
2056
2083
  async _handleSave(request, docId) {
2057
2084
  const body = await request.json();
@@ -2059,6 +2086,15 @@ function createDatabaseDO(config = {}) {
2059
2086
  if (!modelName || !id) {
2060
2087
  return this._errorResponse("modelName and id are required", 400);
2061
2088
  }
2089
+ if (!data) {
2090
+ return this._errorResponse("data is required", 400);
2091
+ }
2092
+ if (data) {
2093
+ const reservedError = this._checkReservedFields(data);
2094
+ if (reservedError) {
2095
+ return this._errorResponse(reservedError, 400);
2096
+ }
2097
+ }
2062
2098
  if (condition && !this._checkCondition(modelName, id, condition)) {
2063
2099
  return this._errorResponse(
2064
2100
  `Condition not met for ${modelName}/${id}`,
@@ -2077,6 +2113,7 @@ function createDatabaseDO(config = {}) {
2077
2113
  modelName,
2078
2114
  docId,
2079
2115
  request,
2116
+ engine: this._engine,
2080
2117
  id,
2081
2118
  data,
2082
2119
  stringSets,
@@ -2115,6 +2152,10 @@ function createDatabaseDO(config = {}) {
2115
2152
  if (!modelName || !id || !data) {
2116
2153
  return this._errorResponse("modelName, id, and data are required", 400);
2117
2154
  }
2155
+ const reservedError = this._checkReservedFields(data);
2156
+ if (reservedError) {
2157
+ return this._errorResponse(reservedError, 400);
2158
+ }
2118
2159
  if (!this._engine.recordExists(modelName, id)) {
2119
2160
  return this._errorResponse(`Record ${modelName}/${id} not found`, 404);
2120
2161
  }
@@ -2129,6 +2170,7 @@ function createDatabaseDO(config = {}) {
2129
2170
  modelName,
2130
2171
  docId,
2131
2172
  request,
2173
+ engine: this._engine,
2132
2174
  id,
2133
2175
  data,
2134
2176
  stringSets,
@@ -2174,11 +2216,21 @@ function createDatabaseDO(config = {}) {
2174
2216
  );
2175
2217
  }
2176
2218
  if (hooks?.beforeDelete) {
2219
+ let record = null;
2220
+ const rows = this._engine.execSqlSync(
2221
+ "SELECT id, type, data_json FROM records WHERE id = ? AND type = ?",
2222
+ [id, modelName]
2223
+ );
2224
+ if (rows.length > 0) {
2225
+ record = this._parseRow(rows[0]);
2226
+ }
2177
2227
  const ctx = {
2178
2228
  modelName,
2179
2229
  docId,
2180
2230
  request,
2181
- id
2231
+ engine: this._engine,
2232
+ id,
2233
+ record
2182
2234
  };
2183
2235
  const result = await hooks.beforeDelete(ctx);
2184
2236
  if (!result.allow) {
@@ -2212,12 +2264,20 @@ function createDatabaseDO(config = {}) {
2212
2264
  400
2213
2265
  );
2214
2266
  }
2267
+ const reservedError = this._checkReservedFields(op.data);
2268
+ if (reservedError) {
2269
+ return this._errorResponse(
2270
+ `Operation ${i}: ${reservedError}`,
2271
+ 400
2272
+ );
2273
+ }
2215
2274
  if (hooks?.beforeSave) {
2216
2275
  const isNew = op.op === "save" ? !this._engine.recordExists(op.modelName, op.id) : false;
2217
2276
  const ctx = {
2218
2277
  modelName: op.modelName,
2219
2278
  docId,
2220
2279
  request,
2280
+ engine: this._engine,
2221
2281
  id: op.id,
2222
2282
  data: op.data,
2223
2283
  stringSets: op.stringSets,
@@ -2230,11 +2290,21 @@ function createDatabaseDO(config = {}) {
2230
2290
  }
2231
2291
  } else if (op.op === "delete") {
2232
2292
  if (hooks?.beforeDelete) {
2293
+ let record = null;
2294
+ const rows = this._engine.execSqlSync(
2295
+ "SELECT id, type, data_json FROM records WHERE id = ? AND type = ?",
2296
+ [op.id, op.modelName]
2297
+ );
2298
+ if (rows.length > 0) {
2299
+ record = this._parseRow(rows[0]);
2300
+ }
2233
2301
  const ctx = {
2234
2302
  modelName: op.modelName,
2235
2303
  docId,
2236
2304
  request,
2237
- id: op.id
2305
+ engine: this._engine,
2306
+ id: op.id,
2307
+ record
2238
2308
  };
2239
2309
  const result = await hooks.beforeDelete(ctx);
2240
2310
  if (!result.allow) {
@@ -2459,6 +2529,7 @@ function createDatabaseDO(config = {}) {
2459
2529
  modelName,
2460
2530
  docId,
2461
2531
  request,
2532
+ engine: this._engine,
2462
2533
  filter
2463
2534
  };
2464
2535
  const result = await hooks.beforeQuery(ctx);
@@ -2571,6 +2642,7 @@ function createDatabaseDO(config = {}) {
2571
2642
  modelName,
2572
2643
  docId,
2573
2644
  request,
2645
+ engine: this._engine,
2574
2646
  filter
2575
2647
  };
2576
2648
  const result = await hooks.beforeQuery(ctx);
@@ -3056,6 +3128,23 @@ function createDatabaseDO(config = {}) {
3056
3128
  const response = { modelName, fields };
3057
3129
  return Response.json(response);
3058
3130
  }
3131
+ /** @internal — List all known model names from records and _model_fields */
3132
+ _handleModelList() {
3133
+ const fromRecords = this._engine.execSqlSync(
3134
+ "SELECT DISTINCT type FROM records ORDER BY type"
3135
+ );
3136
+ const fromFields = this._engine.execSqlSync(
3137
+ "SELECT DISTINCT model_name FROM _model_fields ORDER BY model_name"
3138
+ );
3139
+ const fromIndexes = this._engine.execSqlSync(
3140
+ "SELECT DISTINCT model_name FROM _indexes ORDER BY model_name"
3141
+ );
3142
+ const modelSet = /* @__PURE__ */ new Set();
3143
+ for (const row of fromRecords) modelSet.add(row.type);
3144
+ for (const row of fromFields) modelSet.add(row.model_name);
3145
+ for (const row of fromIndexes) modelSet.add(row.model_name);
3146
+ return Response.json({ models: Array.from(modelSet).sort() });
3147
+ }
3059
3148
  /** @internal */
3060
3149
  _errorResponse(message, status) {
3061
3150
  const body = { error: message };
@@ -608,6 +608,8 @@ interface HookContext {
608
608
  docId: string;
609
609
  /** The raw request (for reading headers, auth tokens, etc.) */
610
610
  request: Request;
611
+ /** The DO's SQLite engine (for direct queries, e.g. lookup functions) */
612
+ engine: any;
611
613
  }
612
614
  /** Context for beforeSave hooks */
613
615
  interface BeforeSaveContext extends HookContext {
@@ -624,6 +626,8 @@ interface BeforeSaveContext extends HookContext {
624
626
  interface BeforeDeleteContext extends HookContext {
625
627
  /** Record ID being deleted */
626
628
  id: string;
629
+ /** The existing record being deleted (parsed from data_json) */
630
+ record: Record<string, any> | null;
627
631
  }
628
632
  /** Context for beforeQuery hooks */
629
633
  interface BeforeQueryContext extends HookContext {
@@ -632,6 +636,11 @@ interface BeforeQueryContext extends HookContext {
632
636
  /** Query options (sort, limit, etc.) */
633
637
  options?: QueryOptions;
634
638
  }
639
+ /** Context for afterQuery hooks */
640
+ interface AfterQueryContext extends HookContext {
641
+ /** The query results to filter */
642
+ results: Record<string, any>[];
643
+ }
635
644
  /** Result from beforeSave/beforeDelete hooks */
636
645
  interface HookResult {
637
646
  allow: boolean;
@@ -643,11 +652,17 @@ interface BeforeQueryResult extends HookResult {
643
652
  /** Additional filter merged into the query via $and */
644
653
  injectFilter?: DocumentFilter;
645
654
  }
655
+ /** Result from afterQuery hooks — returns filtered results */
656
+ interface AfterQueryResult {
657
+ /** The filtered results to return */
658
+ results: Record<string, any>[];
659
+ }
646
660
  /** Hook definitions for createDatabaseDO */
647
661
  interface DatabaseDOHooks {
648
662
  beforeSave?: (ctx: BeforeSaveContext) => Promise<HookResult>;
649
663
  beforeDelete?: (ctx: BeforeDeleteContext) => Promise<HookResult>;
650
664
  beforeQuery?: (ctx: BeforeQueryContext) => Promise<BeforeQueryResult>;
665
+ afterQuery?: (ctx: AfterQueryContext) => Promise<AfterQueryResult>;
651
666
  }
652
667
 
653
668
  /**
@@ -1346,4 +1361,4 @@ interface DoDb {
1346
1361
  */
1347
1362
  declare function connectDoDb(options: ConnectDoDbOptions): DoDb;
1348
1363
 
1349
- export { type AggregateRequest, type AggregateResponse, type AggregationOperation, type AggregationOptions, type AggregationResult, type BatchOperation, type BatchOperationResult, type BatchRequest, type BatchResponse, type BeforeDeleteContext, type BeforeQueryContext, type BeforeQueryResult, type BeforeSaveContext, type ConnectDoDbOptions, type CountRequest, type CountResponse, DOClientEngine, type DOClientEngineConfig, type DatabaseDOHooks, type DeleteRequest, type DeleteResponse, type DoDb, type DocumentFilter, type DropIndexRequest, type DropIndexResponse, type DropUniqueConstraintRequest, type DropUniqueConstraintResponse, type ErrorResponse, type GroupByField, type HookContext, type HookResult, type IncrementRequest, type IncrementResponse, type IndexEntry, type IndexListResponse, type InitJsBaoDOOptions, type InitJsBaoDOResult, type ModelAccessor, type PaginatedResult, type PatchOptions, type PatchRequest, type PatchResponse, type ProjectionSpec, type QueryOptions, type QueryRequest, type QueryResponse, type RegisterIndexRequest, type RegisterIndexResponse, type RegisterUniqueConstraintRequest, type RegisterUniqueConstraintResponse, type SaveOptions, type SaveRequest, type SaveResponse, type SortSpec, type StringSetMembership, type StringSetUpdateRequest, type StringSetUpdateResponse, type SyncIndexesRequest, type SyncIndexesResponse, type UniqueConstraintEntry, type UniqueConstraintListResponse, type WriteCondition, connectDoDb, getActiveDOEngine, initJsBaoDO, resetJsBaoDO };
1364
+ export { type AfterQueryContext, type AfterQueryResult, type AggregateRequest, type AggregateResponse, type AggregationOperation, type AggregationOptions, type AggregationResult, type BatchOperation, type BatchOperationResult, type BatchRequest, type BatchResponse, type BeforeDeleteContext, type BeforeQueryContext, type BeforeQueryResult, type BeforeSaveContext, type ConnectDoDbOptions, type CountRequest, type CountResponse, DOClientEngine, type DOClientEngineConfig, type DatabaseDOHooks, type DeleteRequest, type DeleteResponse, type DoDb, type DocumentFilter, type DropIndexRequest, type DropIndexResponse, type DropUniqueConstraintRequest, type DropUniqueConstraintResponse, type ErrorResponse, type GroupByField, type HookContext, type HookResult, type IncrementRequest, type IncrementResponse, type IndexEntry, type IndexListResponse, type InitJsBaoDOOptions, type InitJsBaoDOResult, type ModelAccessor, type PaginatedResult, type PatchOptions, type PatchRequest, type PatchResponse, type ProjectionSpec, type QueryOptions, type QueryRequest, type QueryResponse, type RegisterIndexRequest, type RegisterIndexResponse, type RegisterUniqueConstraintRequest, type RegisterUniqueConstraintResponse, type SaveOptions, type SaveRequest, type SaveResponse, type SortSpec, type StringSetMembership, type StringSetUpdateRequest, type StringSetUpdateResponse, type SyncIndexesRequest, type SyncIndexesResponse, type UniqueConstraintEntry, type UniqueConstraintListResponse, type WriteCondition, connectDoDb, getActiveDOEngine, initJsBaoDO, resetJsBaoDO };
@@ -608,6 +608,8 @@ interface HookContext {
608
608
  docId: string;
609
609
  /** The raw request (for reading headers, auth tokens, etc.) */
610
610
  request: Request;
611
+ /** The DO's SQLite engine (for direct queries, e.g. lookup functions) */
612
+ engine: any;
611
613
  }
612
614
  /** Context for beforeSave hooks */
613
615
  interface BeforeSaveContext extends HookContext {
@@ -624,6 +626,8 @@ interface BeforeSaveContext extends HookContext {
624
626
  interface BeforeDeleteContext extends HookContext {
625
627
  /** Record ID being deleted */
626
628
  id: string;
629
+ /** The existing record being deleted (parsed from data_json) */
630
+ record: Record<string, any> | null;
627
631
  }
628
632
  /** Context for beforeQuery hooks */
629
633
  interface BeforeQueryContext extends HookContext {
@@ -632,6 +636,11 @@ interface BeforeQueryContext extends HookContext {
632
636
  /** Query options (sort, limit, etc.) */
633
637
  options?: QueryOptions;
634
638
  }
639
+ /** Context for afterQuery hooks */
640
+ interface AfterQueryContext extends HookContext {
641
+ /** The query results to filter */
642
+ results: Record<string, any>[];
643
+ }
635
644
  /** Result from beforeSave/beforeDelete hooks */
636
645
  interface HookResult {
637
646
  allow: boolean;
@@ -643,11 +652,17 @@ interface BeforeQueryResult extends HookResult {
643
652
  /** Additional filter merged into the query via $and */
644
653
  injectFilter?: DocumentFilter;
645
654
  }
655
+ /** Result from afterQuery hooks — returns filtered results */
656
+ interface AfterQueryResult {
657
+ /** The filtered results to return */
658
+ results: Record<string, any>[];
659
+ }
646
660
  /** Hook definitions for createDatabaseDO */
647
661
  interface DatabaseDOHooks {
648
662
  beforeSave?: (ctx: BeforeSaveContext) => Promise<HookResult>;
649
663
  beforeDelete?: (ctx: BeforeDeleteContext) => Promise<HookResult>;
650
664
  beforeQuery?: (ctx: BeforeQueryContext) => Promise<BeforeQueryResult>;
665
+ afterQuery?: (ctx: AfterQueryContext) => Promise<AfterQueryResult>;
651
666
  }
652
667
 
653
668
  /**
@@ -1346,4 +1361,4 @@ interface DoDb {
1346
1361
  */
1347
1362
  declare function connectDoDb(options: ConnectDoDbOptions): DoDb;
1348
1363
 
1349
- export { type AggregateRequest, type AggregateResponse, type AggregationOperation, type AggregationOptions, type AggregationResult, type BatchOperation, type BatchOperationResult, type BatchRequest, type BatchResponse, type BeforeDeleteContext, type BeforeQueryContext, type BeforeQueryResult, type BeforeSaveContext, type ConnectDoDbOptions, type CountRequest, type CountResponse, DOClientEngine, type DOClientEngineConfig, type DatabaseDOHooks, type DeleteRequest, type DeleteResponse, type DoDb, type DocumentFilter, type DropIndexRequest, type DropIndexResponse, type DropUniqueConstraintRequest, type DropUniqueConstraintResponse, type ErrorResponse, type GroupByField, type HookContext, type HookResult, type IncrementRequest, type IncrementResponse, type IndexEntry, type IndexListResponse, type InitJsBaoDOOptions, type InitJsBaoDOResult, type ModelAccessor, type PaginatedResult, type PatchOptions, type PatchRequest, type PatchResponse, type ProjectionSpec, type QueryOptions, type QueryRequest, type QueryResponse, type RegisterIndexRequest, type RegisterIndexResponse, type RegisterUniqueConstraintRequest, type RegisterUniqueConstraintResponse, type SaveOptions, type SaveRequest, type SaveResponse, type SortSpec, type StringSetMembership, type StringSetUpdateRequest, type StringSetUpdateResponse, type SyncIndexesRequest, type SyncIndexesResponse, type UniqueConstraintEntry, type UniqueConstraintListResponse, type WriteCondition, connectDoDb, getActiveDOEngine, initJsBaoDO, resetJsBaoDO };
1364
+ export { type AfterQueryContext, type AfterQueryResult, type AggregateRequest, type AggregateResponse, type AggregationOperation, type AggregationOptions, type AggregationResult, type BatchOperation, type BatchOperationResult, type BatchRequest, type BatchResponse, type BeforeDeleteContext, type BeforeQueryContext, type BeforeQueryResult, type BeforeSaveContext, type ConnectDoDbOptions, type CountRequest, type CountResponse, DOClientEngine, type DOClientEngineConfig, type DatabaseDOHooks, type DeleteRequest, type DeleteResponse, type DoDb, type DocumentFilter, type DropIndexRequest, type DropIndexResponse, type DropUniqueConstraintRequest, type DropUniqueConstraintResponse, type ErrorResponse, type GroupByField, type HookContext, type HookResult, type IncrementRequest, type IncrementResponse, type IndexEntry, type IndexListResponse, type InitJsBaoDOOptions, type InitJsBaoDOResult, type ModelAccessor, type PaginatedResult, type PatchOptions, type PatchRequest, type PatchResponse, type ProjectionSpec, type QueryOptions, type QueryRequest, type QueryResponse, type RegisterIndexRequest, type RegisterIndexResponse, type RegisterUniqueConstraintRequest, type RegisterUniqueConstraintResponse, type SaveOptions, type SaveRequest, type SaveResponse, type SortSpec, type StringSetMembership, type StringSetUpdateRequest, type StringSetUpdateResponse, type SyncIndexesRequest, type SyncIndexesResponse, type UniqueConstraintEntry, type UniqueConstraintListResponse, type WriteCondition, connectDoDb, getActiveDOEngine, initJsBaoDO, resetJsBaoDO };
package/dist/codegen.cjs CHANGED
@@ -1189,7 +1189,7 @@ var SchemaExtractor = class {
1189
1189
  // package.json
1190
1190
  var package_default = {
1191
1191
  name: "js-bao",
1192
- version: "0.3.0-alpha.0",
1192
+ version: "0.3.0-alpha.2",
1193
1193
  description: "A library providing data modeling capabilities which support live updates and queries.",
1194
1194
  types: "dist/index.d.ts",
1195
1195
  type: "module",
@@ -1273,7 +1273,7 @@ var package_default = {
1273
1273
  ulid: "^3.0.0"
1274
1274
  },
1275
1275
  devDependencies: {
1276
- "@types/better-sqlite3": "^7.6.9",
1276
+ "@types/better-sqlite3": "^7.6.13",
1277
1277
  "@types/node": "^20.17.51",
1278
1278
  "@types/sql.js": "^1.4.9",
1279
1279
  commander: "^11.0.0",
@@ -1287,7 +1287,7 @@ var package_default = {
1287
1287
  yjs: "^13.6.18"
1288
1288
  },
1289
1289
  optionalDependencies: {
1290
- "better-sqlite3": "^9.6.0"
1290
+ "better-sqlite3": "^12.6.2"
1291
1291
  },
1292
1292
  keywords: [
1293
1293
  "yjs",
package/dist/index.cjs CHANGED
@@ -6250,12 +6250,16 @@ async function resetJsBao() {
6250
6250
  ormInitializationPromise = null;
6251
6251
  const { BaseModel: BaseModel3 } = await Promise.resolve().then(() => (init_BaseModel(), BaseModel_exports));
6252
6252
  BaseModel3.dbInstance = null;
6253
- Logger.debug("[resetJsBao] BaseModel database instance cleared.");
6253
+ BaseModel3.connectedDocuments = /* @__PURE__ */ new Map();
6254
+ BaseModel3.documentYMaps = /* @__PURE__ */ new Map();
6255
+ BaseModel3.clearModelDefaultDocumentIds();
6256
+ BaseModel3.clearGlobalDefaultDocumentId();
6257
+ Logger.debug("[resetJsBao] BaseModel database instance and document state cleared.");
6254
6258
  const modelRegistryInstance = ModelRegistry.getInstance();
6255
6259
  modelRegistryInstance.clearSessionState();
6256
6260
  Logger.debug("[resetJsBao] ModelRegistry session state cleared.");
6257
6261
  Logger.info(
6258
- "[resetJsBao] js-bao initialization promise has been reset. DB engine (if any) destroyed. ModelRegistry session cleared."
6262
+ "[resetJsBao] js-bao state fully reset. DB engine destroyed. Document mappings cleared. ModelRegistry session cleared."
6259
6263
  );
6260
6264
  }
6261
6265
 
package/dist/index.js CHANGED
@@ -6200,12 +6200,16 @@ async function resetJsBao() {
6200
6200
  ormInitializationPromise = null;
6201
6201
  const { BaseModel: BaseModel3 } = await Promise.resolve().then(() => (init_BaseModel(), BaseModel_exports));
6202
6202
  BaseModel3.dbInstance = null;
6203
- Logger.debug("[resetJsBao] BaseModel database instance cleared.");
6203
+ BaseModel3.connectedDocuments = /* @__PURE__ */ new Map();
6204
+ BaseModel3.documentYMaps = /* @__PURE__ */ new Map();
6205
+ BaseModel3.clearModelDefaultDocumentIds();
6206
+ BaseModel3.clearGlobalDefaultDocumentId();
6207
+ Logger.debug("[resetJsBao] BaseModel database instance and document state cleared.");
6204
6208
  const modelRegistryInstance = ModelRegistry.getInstance();
6205
6209
  modelRegistryInstance.clearSessionState();
6206
6210
  Logger.debug("[resetJsBao] ModelRegistry session state cleared.");
6207
6211
  Logger.info(
6208
- "[resetJsBao] js-bao initialization promise has been reset. DB engine (if any) destroyed. ModelRegistry session cleared."
6212
+ "[resetJsBao] js-bao state fully reset. DB engine destroyed. Document mappings cleared. ModelRegistry session cleared."
6209
6213
  );
6210
6214
  }
6211
6215
 
package/dist/node.cjs CHANGED
@@ -6435,12 +6435,16 @@ async function resetJsBao() {
6435
6435
  ormInitializationPromise = null;
6436
6436
  const { BaseModel: BaseModel3 } = await Promise.resolve().then(() => (init_BaseModel(), BaseModel_exports));
6437
6437
  BaseModel3.dbInstance = null;
6438
- Logger.debug("[resetJsBao] BaseModel database instance cleared.");
6438
+ BaseModel3.connectedDocuments = /* @__PURE__ */ new Map();
6439
+ BaseModel3.documentYMaps = /* @__PURE__ */ new Map();
6440
+ BaseModel3.clearModelDefaultDocumentIds();
6441
+ BaseModel3.clearGlobalDefaultDocumentId();
6442
+ Logger.debug("[resetJsBao] BaseModel database instance and document state cleared.");
6439
6443
  const modelRegistryInstance = ModelRegistry.getInstance();
6440
6444
  modelRegistryInstance.clearSessionState();
6441
6445
  Logger.debug("[resetJsBao] ModelRegistry session state cleared.");
6442
6446
  Logger.info(
6443
- "[resetJsBao] js-bao initialization promise has been reset. DB engine (if any) destroyed. ModelRegistry session cleared."
6447
+ "[resetJsBao] js-bao state fully reset. DB engine destroyed. Document mappings cleared. ModelRegistry session cleared."
6444
6448
  );
6445
6449
  }
6446
6450
 
package/dist/node.js CHANGED
@@ -6382,12 +6382,16 @@ async function resetJsBao() {
6382
6382
  ormInitializationPromise = null;
6383
6383
  const { BaseModel: BaseModel3 } = await Promise.resolve().then(() => (init_BaseModel(), BaseModel_exports));
6384
6384
  BaseModel3.dbInstance = null;
6385
- Logger.debug("[resetJsBao] BaseModel database instance cleared.");
6385
+ BaseModel3.connectedDocuments = /* @__PURE__ */ new Map();
6386
+ BaseModel3.documentYMaps = /* @__PURE__ */ new Map();
6387
+ BaseModel3.clearModelDefaultDocumentIds();
6388
+ BaseModel3.clearGlobalDefaultDocumentId();
6389
+ Logger.debug("[resetJsBao] BaseModel database instance and document state cleared.");
6386
6390
  const modelRegistryInstance = ModelRegistry.getInstance();
6387
6391
  modelRegistryInstance.clearSessionState();
6388
6392
  Logger.debug("[resetJsBao] ModelRegistry session state cleared.");
6389
6393
  Logger.info(
6390
- "[resetJsBao] js-bao initialization promise has been reset. DB engine (if any) destroyed. ModelRegistry session cleared."
6394
+ "[resetJsBao] js-bao state fully reset. DB engine destroyed. Document mappings cleared. ModelRegistry session cleared."
6391
6395
  );
6392
6396
  }
6393
6397
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "js-bao",
3
- "version": "0.3.0-alpha.0",
3
+ "version": "0.3.0-alpha.2",
4
4
  "description": "A library providing data modeling capabilities which support live updates and queries.",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -84,7 +84,7 @@
84
84
  "ulid": "^3.0.0"
85
85
  },
86
86
  "devDependencies": {
87
- "@types/better-sqlite3": "^7.6.9",
87
+ "@types/better-sqlite3": "^7.6.13",
88
88
  "@types/node": "^20.17.51",
89
89
  "@types/sql.js": "^1.4.9",
90
90
  "commander": "^11.0.0",
@@ -98,7 +98,7 @@
98
98
  "yjs": "^13.6.18"
99
99
  },
100
100
  "optionalDependencies": {
101
- "better-sqlite3": "^9.6.0"
101
+ "better-sqlite3": "^12.6.2"
102
102
  },
103
103
  "keywords": [
104
104
  "yjs",