{"version":3,"file":"moltendb-web-angular.mjs","sources":["../../../src/lib/moltendb.provider.ts","../../../src/lib/moltendb.service.ts","../../../src/lib/moltendb.resource.ts","../../../src/lib/moltendb.client.ts","../../../src/public-api.ts","../../../src/moltendb-web-angular.ts"],"sourcesContent":["import {\n  EnvironmentProviders,\n  InjectionToken,\n  makeEnvironmentProviders,\n} from \"@angular/core\";\nimport { MoltenDbOptions } from \"@moltendb-web/core\";\n\nexport interface AngularMoltenDbOptions extends MoltenDbOptions {\n  name: string;\n}\n\nexport const MOLTEN_CONFIG = new InjectionToken<AngularMoltenDbOptions>(\n  \"MOLTEN_CONFIG\"\n);\n\nexport function provideMoltenDb(\n  config: AngularMoltenDbOptions\n): EnvironmentProviders {\n  return makeEnvironmentProviders([\n    { provide: MOLTEN_CONFIG, useValue: config },\n  ]);\n}\n","import { inject, Injectable, PLATFORM_ID, signal } from \"@angular/core\";\nimport { isPlatformBrowser } from \"@angular/common\";\nimport { MoltenDb } from \"@moltendb-web/core\";\nimport { MoltenDbClient, MoltenTransport } from \"@moltendb-web/query\";\nimport { MOLTEN_CONFIG } from \"./moltendb.provider\";\n\n/**\n * Thrown by the server-side stubs whenever code tries to actually reach the\n * MoltenDb engine while running outside the browser (SSR / prerendering).\n */\nexport const MOLTEN_SSR_ERROR_MESSAGE =\n  \"[MoltenDb] MoltenDb is not available in a server-side rendering context.\";\n\n/**\n * Stand-in for `MoltenDb` used when running outside the browser (SSR / prerendering).\n * It never touches WASM, OPFS, or the Web Locks API. `init()` resolves immediately\n * and `clearOpfs()` is a no-op — there is nothing to boot or clear on the server.\n */\nclass ServerMoltenDb extends MoltenDb {\n  override init(): Promise<void> {\n    return Promise.resolve();\n  }\n\n  override sendMessage(): Promise<never> {\n    return Promise.reject(new Error(MOLTEN_SSR_ERROR_MESSAGE));\n  }\n\n  override async clearOpfs(): Promise<void> {\n    // No OPFS storage exists on the server — nothing to clear.\n  }\n}\n\n/**\n * Stand-in transport used when running outside the browser (SSR / prerendering).\n * Query builder chains (`.collection().set()`, `.get()`, `.delete()`, ...) keep\n * working synchronously — only the terminal `.exec()` call rejects, with a clear,\n * actionable error instead of hanging forever.\n */\nclass ServerTransport implements MoltenTransport {\n  sendMessage(): Promise<never> {\n    return Promise.reject(new Error(MOLTEN_SSR_ERROR_MESSAGE));\n  }\n}\n\n@Injectable({ providedIn: \"root\" })\nexport class MoltenDbService {\n  public db: MoltenDb;\n  public client: MoltenDbClient;\n\n  // Internal signal used by `moltenDbResource()` to know when WASM is booted and\n  // Leader Election is done. @internal — not part of the public API: `MoltenDbService`\n  // itself is never re-exported from `public-api.ts`, and no getter or standalone\n  // `moltenDbReady()`-style function should ever be added to expose this signal.\n  // Stays `false` forever on the server, which is what makes `moltenDbResource()`\n  // skip fetching there with no changes needed on its \"don't fetch\" path.\n  public isReady = signal<boolean>(false);\n\n  constructor() {\n    const config = inject(MOLTEN_CONFIG);\n    const isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n    if (!isBrowser) {\n      // Server: never construct the real engine — no WASM, no OPFS, no Web Locks.\n      this.db = new ServerMoltenDb(config.name, config);\n      this.client = new MoltenDbClient(new ServerTransport());\n      return;\n    }\n\n    this.db = new MoltenDb(config.name, config);\n    this.client = new MoltenDbClient(this.db);\n\n    // Boot the engine and update the signal when done\n    this.db\n      .init()\n      .then(() => {\n        this.isReady.set(true);\n      })\n      .catch((err) => {\n        console.error(\"[MoltenDb] Failed to initialize\", err);\n      });\n  }\n}\n","import {\n  effect,\n  inject,\n  PLATFORM_ID,\n  signal,\n  Signal,\n  untracked,\n} from \"@angular/core\";\nimport { isPlatformBrowser } from \"@angular/common\";\nimport { MoltenDbClient } from \"@moltendb-web/query\";\nimport { MoltenDbService } from \"./moltendb.service\";\n\nexport interface MoltenDbResource<T> {\n  value: Signal<T | undefined>;\n  isLoading: Signal<boolean>;\n  error: Signal<any | null>;\n}\n\nexport interface MoltenDbResourceOptions<T> {\n  /**\n   * Value the `value` signal starts with, before the first fetch resolves in\n   * the browser — and what it stays at (unchanged) on the server, since no\n   * fetch is ever attempted there. Defaults to `undefined` when omitted.\n   */\n  initialValue?: T;\n}\n\nexport function moltenDbResource<T>(\n  collection: string,\n  //  Automatically infer the return type of .collection()\n  queryFn: (\n    collection: ReturnType<MoltenDbClient[\"collection\"]>,\n    client: MoltenDbClient\n  ) => Promise<T>,\n  options?: MoltenDbResourceOptions<T>\n): MoltenDbResource<T> {\n  const molten = inject(MoltenDbService);\n  const isBrowser = isPlatformBrowser(inject(PLATFORM_ID));\n\n  const value = signal<T | undefined>(options?.initialValue);\n  const isLoading = signal<boolean>(false);\n  const error = signal<any | null>(null);\n\n  // Server (SSR/prerendering): MoltenDb never boots here, so resolve to an\n  // explicit, documented empty state — `isLoading()` false, `error()` null,\n  // `value()` at `options?.initialValue` (or `undefined` if none was given) —\n  // synchronously, with no fetch attempted and no hang.\n  if (!isBrowser) {\n    return {\n      value: value.asReadonly(),\n      isLoading: isLoading.asReadonly(),\n      error: error.asReadonly(),\n    };\n  }\n\n  const fetchData = async () => {\n    untracked(() => isLoading.set(true));\n\n    try {\n      // ⚡ Pre-bind the collection and pass it in!\n      const result = await queryFn(\n        molten.client.collection(collection),\n        molten.client\n      );\n      value.set(result);\n      error.set(null);\n    } catch (err: any) {\n      if (err.message?.includes(\"404\")) {\n        value.set([] as any);\n        error.set(null);\n      } else {\n        error.set(err);\n      }\n    } finally {\n      isLoading.set(false);\n    }\n  };\n\n  effect((onCleanup) => {\n    if (!molten.isReady()) return;\n\n    fetchData();\n\n    const unsubscribe = molten.db.subscribe((evt) => {\n      if (evt.collection === collection) fetchData();\n    });\n\n    onCleanup(() => unsubscribe());\n  });\n\n  return {\n    value: value.asReadonly(),\n    isLoading: isLoading.asReadonly(),\n    error: error.asReadonly(),\n  };\n}\n","import { DestroyRef, inject } from \"@angular/core\";\nimport { MoltenDbClient } from \"@moltendb-web/query\";\nimport { DbEvent } from \"@moltendb-web/core\";\nimport { MoltenDbService } from \"./moltendb.service\";\n\n/** Functional injection hook to access the MoltenDb Query Client. */\nexport function moltendbClient(): MoltenDbClient {\n  return inject(MoltenDbService).client;\n}\n\n/** Returns true if this tab is the Leader (running the WASM worker). */\nexport function moltenDbIsLeader(): boolean {\n  return inject(MoltenDbService).db.isLeader;\n}\n\n/**\n * Flushes and closes the OPFS sync handle.\n * Call this before `moltenDbTerminate()` to avoid \"No modification allowed\" errors.\n */\nexport async function moltenDbClearOpfs(): Promise<void> {\n  await inject(MoltenDbService).db.clearOpfs();\n}\n\n/** Terminates the MoltenDb worker. Call after clearing OPFS storage. */\nexport function moltenDbTerminate(): void {\n  inject(MoltenDbService).db.terminate();\n}\n\n/**\n * Subscribe to real-time MoltenDb mutation events.\n * The subscription is automatically cleaned up when the injection context (component/service) is destroyed.\n * No manual unsubscription or ngOnDestroy needed.\n * Must be run in injection context (component/service).\n */\nexport function moltenDbEvents(listener: (event: DbEvent) => void): void {\n  const unsub = inject(MoltenDbService).db.subscribe(listener);\n  inject(DestroyRef).onDestroy(() => unsub());\n}\n","/*\n * Public API Surface of @moltendb-web/angular\n */\n\nexport * from \"./lib/moltendb.provider\";\nexport * from \"./lib/moltendb.resource\";\nexport * from \"./lib/moltendb.client\";\nexport type { DbEvent } from \"@moltendb-web/core\";\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;MAWa,aAAa,GAAG,IAAI,cAAc,CAC7C,eAAe;AAGX,SAAU,eAAe,CAC7B,MAA8B,EAAA;AAE9B,IAAA,OAAO,wBAAwB,CAAC;AAC9B,QAAA,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE;AAC7C,KAAA,CAAC;AACJ;;ACfA;;;AAGG;AACI,MAAM,wBAAwB,GACnC,0EAA0E;AAE5E;;;;AAIG;AACH,MAAM,cAAe,SAAQ,QAAQ,CAAA;IAC1B,IAAI,GAAA;AACX,QAAA,OAAO,OAAO,CAAC,OAAO,EAAE;IAC1B;IAES,WAAW,GAAA;QAClB,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC5D;AAES,IAAA,MAAM,SAAS,GAAA;;IAExB;AACD;AAED;;;;;AAKG;AACH,MAAM,eAAe,CAAA;IACnB,WAAW,GAAA;QACT,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC5D;AACD;MAGY,eAAe,CAAA;AACnB,IAAA,EAAE;AACF,IAAA,MAAM;;;;;;;AAQN,IAAA,OAAO,GAAG,MAAM,CAAU,KAAK,CAAC;AAEvC,IAAA,WAAA,GAAA;AACE,QAAA,MAAM,MAAM,GAAG,MAAM,CAAC,aAAa,CAAC;QACpC,MAAM,SAAS,GAAG,iBAAiB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAExD,IAAI,CAAC,SAAS,EAAE;;AAEd,YAAA,IAAI,CAAC,EAAE,GAAG,IAAI,cAAc,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC;YACjD,IAAI,CAAC,MAAM,GAAG,IAAI,cAAc,CAAC,IAAI,eAAe,EAAE,CAAC;YACvD;QACF;AAEA,QAAA,IAAI,CAAC,EAAE,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC;QAC3C,IAAI,CAAC,MAAM,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;;AAGzC,QAAA,IAAI,CAAC;AACF,aAAA,IAAI;aACJ,IAAI,CAAC,MAAK;AACT,YAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;AACxB,QAAA,CAAC;AACA,aAAA,KAAK,CAAC,CAAC,GAAG,KAAI;AACb,YAAA,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,GAAG,CAAC;AACvD,QAAA,CAAC,CAAC;IACN;wGAnCW,eAAe,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAf,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,eAAe,cADF,MAAM,EAAA,CAAA;;4FACnB,eAAe,EAAA,UAAA,EAAA,CAAA;kBAD3B,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE;;;ACjB5B,SAAU,gBAAgB,CAC9B,UAAkB;AAClB;AACA,OAGe,EACf,OAAoC,EAAA;AAEpC,IAAA,MAAM,MAAM,GAAG,MAAM,CAAC,eAAe,CAAC;IACtC,MAAM,SAAS,GAAG,iBAAiB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAExD,MAAM,KAAK,GAAG,MAAM,CAAgB,OAAO,EAAE,YAAY,CAAC;AAC1D,IAAA,MAAM,SAAS,GAAG,MAAM,CAAU,KAAK,CAAC;AACxC,IAAA,MAAM,KAAK,GAAG,MAAM,CAAa,IAAI,CAAC;;;;;IAMtC,IAAI,CAAC,SAAS,EAAE;QACd,OAAO;AACL,YAAA,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE;AACzB,YAAA,SAAS,EAAE,SAAS,CAAC,UAAU,EAAE;AACjC,YAAA,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE;SAC1B;IACH;AAEA,IAAA,MAAM,SAAS,GAAG,YAAW;QAC3B,SAAS,CAAC,MAAM,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAEpC,QAAA,IAAI;;AAEF,YAAA,MAAM,MAAM,GAAG,MAAM,OAAO,CAC1B,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,EACpC,MAAM,CAAC,MAAM,CACd;AACD,YAAA,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC;AACjB,YAAA,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;QACjB;QAAE,OAAO,GAAQ,EAAE;YACjB,IAAI,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE;AAChC,gBAAA,KAAK,CAAC,GAAG,CAAC,EAAS,CAAC;AACpB,gBAAA,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;YACjB;iBAAO;AACL,gBAAA,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;YAChB;QACF;gBAAU;AACR,YAAA,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;QACtB;AACF,IAAA,CAAC;AAED,IAAA,MAAM,CAAC,CAAC,SAAS,KAAI;AACnB,QAAA,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE;YAAE;AAEvB,QAAA,SAAS,EAAE;QAEX,MAAM,WAAW,GAAG,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,GAAG,KAAI;AAC9C,YAAA,IAAI,GAAG,CAAC,UAAU,KAAK,UAAU;AAAE,gBAAA,SAAS,EAAE;AAChD,QAAA,CAAC,CAAC;AAEF,QAAA,SAAS,CAAC,MAAM,WAAW,EAAE,CAAC;AAChC,IAAA,CAAC,CAAC;IAEF,OAAO;AACL,QAAA,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE;AACzB,QAAA,SAAS,EAAE,SAAS,CAAC,UAAU,EAAE;AACjC,QAAA,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE;KAC1B;AACH;;AC1FA;SACgB,cAAc,GAAA;AAC5B,IAAA,OAAO,MAAM,CAAC,eAAe,CAAC,CAAC,MAAM;AACvC;AAEA;SACgB,gBAAgB,GAAA;IAC9B,OAAO,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,QAAQ;AAC5C;AAEA;;;AAGG;AACI,eAAe,iBAAiB,GAAA;IACrC,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,SAAS,EAAE;AAC9C;AAEA;SACgB,iBAAiB,GAAA;IAC/B,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,SAAS,EAAE;AACxC;AAEA;;;;;AAKG;AACG,SAAU,cAAc,CAAC,QAAkC,EAAA;AAC/D,IAAA,MAAM,KAAK,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC;AAC5D,IAAA,MAAM,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,MAAM,KAAK,EAAE,CAAC;AAC7C;;ACrCA;;AAEG;;ACFH;;AAEG;;;;"}