@korajs/core 1.0.0-beta.5 → 1.0.0-beta.7

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.
@@ -1,5 +1,5 @@
1
- import { p as KoraEventEmitter } from '../events-DhblJN4r.cjs';
2
- import { S as ScopeMap } from '../build-scope-map-K25AyQXb.cjs';
1
+ import { p as KoraEventEmitter } from '../events-CT9y24ht.cjs';
2
+ import { S as ScopeMap } from '../build-scope-map-Bm6Lqo9F.cjs';
3
3
 
4
4
  /** Sync status shape consumed by framework binding hooks (matches {@link SyncStatusInfo} in `@korajs/sync`). */
5
5
  interface KoraBindingSyncStatus {
@@ -1,5 +1,5 @@
1
- import { p as KoraEventEmitter } from '../events-DhblJN4r.js';
2
- import { S as ScopeMap } from '../build-scope-map-BvdTzmm4.js';
1
+ import { p as KoraEventEmitter } from '../events-CT9y24ht.js';
2
+ import { S as ScopeMap } from '../build-scope-map-C60lT-4I.js';
3
3
 
4
4
  /** Sync status shape consumed by framework binding hooks (matches {@link SyncStatusInfo} in `@korajs/sync`). */
5
5
  interface KoraBindingSyncStatus {
@@ -1,4 +1,4 @@
1
- import { S as SchemaDefinition } from './events-DhblJN4r.cjs';
1
+ import { S as SchemaDefinition } from './events-CT9y24ht.cjs';
2
2
 
3
3
  /**
4
4
  * Per-collection scope map: `{ collectionName: { field: value, ... } }`
@@ -1,4 +1,4 @@
1
- import { S as SchemaDefinition } from './events-DhblJN4r.js';
1
+ import { S as SchemaDefinition } from './events-CT9y24ht.js';
2
2
 
3
3
  /**
4
4
  * Per-collection scope map: `{ collectionName: { field: value, ... } }`
@@ -912,6 +912,18 @@ type KoraEvent = {
912
912
  */
913
913
  reason: 'lock-conflict' | 'timeout' | 'unsupported';
914
914
  message: string;
915
+ } | {
916
+ /**
917
+ * A preferred storage backend could not provide durable storage, so Kora
918
+ * promoted the app to another durable backend before user code observed the
919
+ * store. This is informational: data still survives reloads.
920
+ */
921
+ type: 'store:storage-fallback';
922
+ dbName: string;
923
+ from: 'opfs' | 'sqlite-wasm';
924
+ to: 'indexeddb';
925
+ reason: 'lock-conflict' | 'timeout' | 'unsupported';
926
+ message: string;
915
927
  } | {
916
928
  /**
917
929
  * Another runtime on this origin was already using this database name, so
@@ -912,6 +912,18 @@ type KoraEvent = {
912
912
  */
913
913
  reason: 'lock-conflict' | 'timeout' | 'unsupported';
914
914
  message: string;
915
+ } | {
916
+ /**
917
+ * A preferred storage backend could not provide durable storage, so Kora
918
+ * promoted the app to another durable backend before user code observed the
919
+ * store. This is informational: data still survives reloads.
920
+ */
921
+ type: 'store:storage-fallback';
922
+ dbName: string;
923
+ from: 'opfs' | 'sqlite-wasm';
924
+ to: 'indexeddb';
925
+ reason: 'lock-conflict' | 'timeout' | 'unsupported';
926
+ message: string;
915
927
  } | {
916
928
  /**
917
929
  * Another runtime on this origin was already using this database name, so
package/dist/index.cjs CHANGED
@@ -2378,10 +2378,17 @@ function validateFieldValue(collection, fieldName, descriptor, value) {
2378
2378
  break;
2379
2379
  }
2380
2380
  case "json": {
2381
- if (!isJsonSerializable(value)) {
2381
+ const nonJson = findNonJsonSerializable(value, fieldName);
2382
+ if (nonJson) {
2382
2383
  throw new SchemaValidationError(
2383
- `Field "${fieldName}" in collection "${collection}" must be JSON-serializable, got ${describeType(value)}`,
2384
- { collection, field: fieldName, expectedType: "json", receivedType: describeType(value) }
2384
+ `Field "${fieldName}" in collection "${collection}" must be JSON-serializable; found ${nonJson.receivedType} at "${nonJson.path}"`,
2385
+ {
2386
+ collection,
2387
+ field: fieldName,
2388
+ expectedType: "json",
2389
+ receivedType: nonJson.receivedType,
2390
+ path: nonJson.path
2391
+ }
2385
2392
  );
2386
2393
  }
2387
2394
  break;
@@ -2418,21 +2425,41 @@ function isPlainObject(value) {
2418
2425
  const proto = Object.getPrototypeOf(value);
2419
2426
  return proto === null || proto === Object.prototype;
2420
2427
  }
2421
- function isJsonSerializable(value) {
2428
+ function findNonJsonSerializable(value, path, seen = /* @__PURE__ */ new WeakSet()) {
2422
2429
  if (value === null) {
2423
- return true;
2430
+ return null;
2424
2431
  }
2425
2432
  const type = typeof value;
2426
2433
  if (type === "string" || type === "number" || type === "boolean") {
2427
- return Number.isFinite(value) || type !== "number";
2434
+ if (type === "number" && !Number.isFinite(value)) {
2435
+ return { path, receivedType: describeType(value) };
2436
+ }
2437
+ return null;
2438
+ }
2439
+ if (type === "undefined" || type === "function" || type === "symbol" || type === "bigint") {
2440
+ return { path, receivedType: describeType(value) };
2428
2441
  }
2429
2442
  if (Array.isArray(value)) {
2430
- return value.every(isJsonSerializable);
2443
+ for (let index = 0; index < value.length; index++) {
2444
+ const invalid = findNonJsonSerializable(value[index], `${path}[${index}]`, seen);
2445
+ if (invalid) return invalid;
2446
+ }
2447
+ return null;
2431
2448
  }
2432
2449
  if (type === "object") {
2433
- return Object.values(value).every(isJsonSerializable);
2450
+ const objectValue = value;
2451
+ if (seen.has(objectValue)) {
2452
+ return { path, receivedType: "circular object" };
2453
+ }
2454
+ seen.add(objectValue);
2455
+ for (const [key, nestedValue] of Object.entries(objectValue)) {
2456
+ const invalid = findNonJsonSerializable(nestedValue, `${path}.${key}`, seen);
2457
+ if (invalid) return invalid;
2458
+ }
2459
+ seen.delete(objectValue);
2460
+ return null;
2434
2461
  }
2435
- return false;
2462
+ return { path, receivedType: describeType(value) };
2436
2463
  }
2437
2464
  function describeType(value) {
2438
2465
  if (value === null) {