{"version":3,"file":"index.cjs","sources":["../src/shared.ts","../../../../node_modules/@blocksuite/global/dist/utils/assert.js","../src/utils.ts","../src/provider.ts","../src/index.ts"],"sourcesContent":["import type { DBSchema, IDBPDatabase } from 'idb';\nimport type { DataSourceAdapter } from 'y-provider';\n\nexport const dbVersion = 1;\nexport const DEFAULT_DB_NAME = 'affine-local';\n\nexport function upgradeDB(db: IDBPDatabase<BlockSuiteBinaryDB>) {\n  db.createObjectStore('workspace', { keyPath: 'id' });\n  db.createObjectStore('milestone', { keyPath: 'id' });\n}\n\nexport interface IndexedDBProvider extends DataSourceAdapter {\n  connect: () => void;\n  disconnect: () => void;\n  cleanup: () => Promise<void>;\n  readonly connected: boolean;\n}\n\nexport type UpdateMessage = {\n  timestamp: number;\n  update: Uint8Array;\n};\n\nexport type WorkspacePersist = {\n  id: string;\n  updates: UpdateMessage[];\n};\n\nexport type WorkspaceMilestone = {\n  id: string;\n  milestone: Record<string, Uint8Array>;\n};\n\nexport interface BlockSuiteBinaryDB extends DBSchema {\n  workspace: {\n    key: string;\n    value: WorkspacePersist;\n  };\n  milestone: {\n    key: string;\n    value: WorkspaceMilestone;\n  };\n}\n\nexport interface OldYjsDB extends DBSchema {\n  updates: {\n    key: number;\n    value: Uint8Array;\n  };\n}\n","// https://stackoverflow.com/questions/31538010/test-if-a-variable-is-a-primitive-rather-than-an-object\nexport function isPrimitive(a) {\n    return a !== Object(a);\n}\nexport function assertExists(val, message = 'val does not exist') {\n    if (val === null || val === undefined) {\n        if (message instanceof Error) {\n            throw message;\n        }\n        throw new Error(message);\n    }\n}\nexport function assertNotExists(val, message = 'val exists') {\n    if (val !== null && val !== undefined) {\n        throw new Error(message);\n    }\n}\nexport function isEqual(val, expected) {\n    const a = isPrimitive(val);\n    const b = isPrimitive(expected);\n    if (a && b) {\n        if (!Object.is(val, expected)) {\n            return false;\n        }\n    }\n    else if (a !== b) {\n        return false;\n    }\n    else {\n        if (Array.isArray(val) && Array.isArray(expected)) {\n            if (val.length !== expected.length) {\n                return false;\n            }\n            return val.every((x, i) => isEqual(x, expected[i]));\n        }\n        else if (typeof val === 'object' && typeof expected === 'object') {\n            const obj1 = Object.entries(val);\n            const obj2 = Object.entries(expected);\n            if (obj1.length !== obj2.length) {\n                return false;\n            }\n            return obj1.every((x, i) => isEqual(x, obj2[i]));\n        }\n    }\n    return true;\n}\nexport function assertEquals(val, expected, message = 'val is not same as expected') {\n    if (!isEqual(val, expected)) {\n        throw new Error(message);\n    }\n}\nexport function assertInstanceOf(val, expected, message = 'val is not instance of expected') {\n    if (!(val instanceof expected)) {\n        throw new Error(message);\n    }\n}\n//# sourceMappingURL=assert.js.map","import type { IDBPDatabase } from 'idb';\nimport { openDB } from 'idb';\nimport { applyUpdate, Doc, encodeStateAsUpdate } from 'yjs';\n\nimport type { BlockSuiteBinaryDB, OldYjsDB, UpdateMessage } from './shared';\nimport { dbVersion, DEFAULT_DB_NAME, upgradeDB } from './shared';\n\nlet allDb: IDBDatabaseInfo[];\n\nexport function mergeUpdates(updates: Uint8Array[]) {\n  const doc = new Doc();\n  updates.forEach(update => {\n    applyUpdate(doc, update);\n  });\n  return encodeStateAsUpdate(doc);\n}\n\nasync function databaseExists(name: string): Promise<boolean> {\n  return new Promise(resolve => {\n    const req = indexedDB.open(name);\n    let existed = true;\n    req.onsuccess = function () {\n      req.result.close();\n      if (!existed) {\n        indexedDB.deleteDatabase(name);\n      }\n      resolve(existed);\n    };\n    req.onupgradeneeded = function () {\n      existed = false;\n    };\n  });\n}\n\n/**\n * try to migrate the old database to the new database\n * this function will be removed in the future\n * since we don't need to support the old database\n */\nexport async function tryMigrate(\n  db: IDBPDatabase<BlockSuiteBinaryDB>,\n  id: string,\n  dbName = DEFAULT_DB_NAME\n) {\n  do {\n    if (!allDb || localStorage.getItem(`${dbName}-migration`) !== 'true') {\n      try {\n        allDb = await indexedDB.databases();\n      } catch {\n        // in firefox, `indexedDB.databases` is not existed\n        if (await databaseExists(id)) {\n          await openDB<IDBPDatabase<OldYjsDB>>(id, 1).then(async oldDB => {\n            if (!oldDB.objectStoreNames.contains('updates')) {\n              return;\n            }\n            const t = oldDB\n              .transaction('updates', 'readonly')\n              .objectStore('updates');\n            const updates = await t.getAll();\n            if (\n              !Array.isArray(updates) ||\n              !updates.every(update => update instanceof Uint8Array)\n            ) {\n              return;\n            }\n            const update = mergeUpdates(updates);\n            const workspaceTransaction = db\n              .transaction('workspace', 'readwrite')\n              .objectStore('workspace');\n            const data = await workspaceTransaction.get(id);\n            if (!data) {\n              console.log('upgrading the database');\n              await workspaceTransaction.put({\n                id,\n                updates: [\n                  {\n                    timestamp: Date.now(),\n                    update,\n                  },\n                ],\n              });\n            }\n          });\n          break;\n        }\n      }\n      // run the migration\n      await Promise.all(\n        allDb &&\n          allDb.map(meta => {\n            if (meta.name && meta.version === 1) {\n              const name = meta.name;\n              const version = meta.version;\n              return openDB<IDBPDatabase<OldYjsDB>>(name, version).then(\n                async oldDB => {\n                  if (!oldDB.objectStoreNames.contains('updates')) {\n                    return;\n                  }\n                  const t = oldDB\n                    .transaction('updates', 'readonly')\n                    .objectStore('updates');\n                  const updates = await t.getAll();\n                  if (\n                    !Array.isArray(updates) ||\n                    !updates.every(update => update instanceof Uint8Array)\n                  ) {\n                    return;\n                  }\n                  const update = mergeUpdates(updates);\n                  const workspaceTransaction = db\n                    .transaction('workspace', 'readwrite')\n                    .objectStore('workspace');\n                  const data = await workspaceTransaction.get(name);\n                  if (!data) {\n                    console.log('upgrading the database');\n                    await workspaceTransaction.put({\n                      id: name,\n                      updates: [\n                        {\n                          timestamp: Date.now(),\n                          update,\n                        },\n                      ],\n                    });\n                  }\n                }\n              );\n            }\n            return void 0;\n          })\n      );\n      localStorage.setItem(`${dbName}-migration`, 'true');\n      break;\n    }\n    // eslint-disable-next-line no-constant-condition\n  } while (false);\n}\n\nexport async function downloadBinary(\n  guid: string,\n  dbName = DEFAULT_DB_NAME\n): Promise<UpdateMessage['update'] | false> {\n  const dbPromise = openDB<BlockSuiteBinaryDB>(dbName, dbVersion, {\n    upgrade: upgradeDB,\n  });\n  const db = await dbPromise;\n  const t = db.transaction('workspace', 'readonly').objectStore('workspace');\n  const doc = await t.get(guid);\n  if (!doc) {\n    return false;\n  } else {\n    return mergeUpdates(doc.updates.map(({ update }) => update));\n  }\n}\n\nexport async function overwriteBinary(\n  guid: string,\n  update: UpdateMessage['update'],\n  dbName = DEFAULT_DB_NAME\n) {\n  const dbPromise = openDB<BlockSuiteBinaryDB>(dbName, dbVersion, {\n    upgrade: upgradeDB,\n  });\n  const db = await dbPromise;\n  const t = db.transaction('workspace', 'readwrite').objectStore('workspace');\n  await t.put({\n    id: guid,\n    updates: [\n      {\n        timestamp: Date.now(),\n        update,\n      },\n    ],\n  });\n}\n\nexport async function pushBinary(\n  guid: string,\n  update: UpdateMessage['update'],\n  dbName = DEFAULT_DB_NAME\n) {\n  const dbPromise = openDB<BlockSuiteBinaryDB>(dbName, dbVersion, {\n    upgrade: upgradeDB,\n  });\n  const db = await dbPromise;\n  const t = db.transaction('workspace', 'readwrite').objectStore('workspace');\n  const doc = await t.get(guid);\n  if (!doc) {\n    await t.put({\n      id: guid,\n      updates: [\n        {\n          timestamp: Date.now(),\n          update,\n        },\n      ],\n    });\n  } else {\n    doc.updates.push({\n      timestamp: Date.now(),\n      update,\n    });\n    await t.put(doc);\n  }\n}\n","import { assertExists } from '@blocksuite/global/utils';\nimport type { IDBPDatabase } from 'idb';\nimport { openDB } from 'idb';\nimport {\n  createLazyProvider,\n  type DocDataSource,\n  writeOperation,\n} from 'y-provider';\nimport type { Doc } from 'yjs';\nimport { diffUpdate, encodeStateVectorFromUpdate } from 'yjs';\n\nimport {\n  type BlockSuiteBinaryDB,\n  dbVersion,\n  DEFAULT_DB_NAME,\n  type IndexedDBProvider,\n  type UpdateMessage,\n  upgradeDB,\n} from './shared';\nimport { mergeUpdates } from './utils';\n\nlet mergeCount = 500;\n\nexport function setMergeCount(count: number) {\n  mergeCount = count;\n}\n\nexport const createIndexedDBDatasource = ({\n  dbName = DEFAULT_DB_NAME,\n  mergeCount,\n}: {\n  dbName?: string;\n  mergeCount?: number;\n}) => {\n  let dbPromise: Promise<IDBPDatabase<BlockSuiteBinaryDB>> | null = null;\n  const getDb = async () => {\n    if (dbPromise === null) {\n      dbPromise = openDB<BlockSuiteBinaryDB>(dbName, dbVersion, {\n        upgrade: upgradeDB,\n      });\n    }\n    return dbPromise;\n  };\n\n  const adapter = {\n    queryDocState: async (guid, options) => {\n      try {\n        const db = await getDb();\n        const store = db\n          .transaction('workspace', 'readonly')\n          .objectStore('workspace');\n        const data = await store.get(guid);\n\n        if (!data) {\n          return false;\n        }\n\n        const { updates } = data;\n        const update = mergeUpdates(updates.map(({ update }) => update));\n\n        const missing = options?.stateVector\n          ? diffUpdate(update, options?.stateVector)\n          : update;\n\n        return { missing, state: encodeStateVectorFromUpdate(update) };\n      } catch (err: any) {\n        if (!err.message?.includes('The database connection is closing.')) {\n          throw err;\n        }\n        return false;\n      }\n    },\n    sendDocUpdate: async (guid, update) => {\n      try {\n        const db = await getDb();\n        const store = db\n          .transaction('workspace', 'readwrite')\n          .objectStore('workspace');\n\n        // TODO: maybe we do not need to get data every time\n        const { updates } = (await store.get(guid)) ?? { updates: [] };\n        let rows: UpdateMessage[] = [\n          ...updates,\n          { timestamp: Date.now(), update },\n        ];\n        if (mergeCount && rows.length >= mergeCount) {\n          const merged = mergeUpdates(rows.map(({ update }) => update));\n          rows = [{ timestamp: Date.now(), update: merged }];\n        }\n        await writeOperation(\n          store.put({\n            id: guid,\n            updates: rows,\n          })\n        );\n      } catch (err: any) {\n        if (!err.message?.includes('The database connection is closing.')) {\n          throw err;\n        }\n      }\n    },\n  } satisfies DocDataSource;\n\n  return {\n    ...adapter,\n    disconnect: () => {\n      getDb()\n        .then(db => db.close())\n        .then(() => {\n          dbPromise = null;\n        })\n        .catch(console.error);\n    },\n    cleanup: async () => {\n      const db = await getDb();\n      await db.clear('workspace');\n    },\n  };\n};\n\n/**\n * We use `doc.guid` as the unique key, please make sure it not changes.\n */\nexport const createIndexedDBProvider = (\n  doc: Doc,\n  dbName: string = DEFAULT_DB_NAME\n): IndexedDBProvider => {\n  const datasource = createIndexedDBDatasource({ dbName, mergeCount });\n  let provider: ReturnType<typeof createLazyProvider> | null = null;\n\n  const apis = {\n    get status() {\n      assertExists(provider);\n      return provider.status;\n    },\n    subscribeStatusChange(onStatusChange) {\n      assertExists(provider);\n      return provider.subscribeStatusChange(onStatusChange);\n    },\n    connect: () => {\n      if (apis.connected) {\n        apis.disconnect();\n      }\n      provider = createLazyProvider(doc, datasource, { origin: 'idb' });\n      provider.connect();\n    },\n    disconnect: () => {\n      datasource?.disconnect();\n      provider?.disconnect();\n      provider = null;\n    },\n    cleanup: async () => {\n      await datasource?.cleanup();\n    },\n    get connected() {\n      return provider?.connected || false;\n    },\n    datasource,\n  } satisfies IndexedDBProvider;\n\n  return apis;\n};\n","import { openDB } from 'idb';\nimport {\n  applyUpdate,\n  Doc,\n  encodeStateAsUpdate,\n  encodeStateVector,\n  UndoManager,\n} from 'yjs';\n\nimport type { BlockSuiteBinaryDB, WorkspaceMilestone } from './shared';\nimport { dbVersion, DEFAULT_DB_NAME, upgradeDB } from './shared';\n\nconst snapshotOrigin = 'snapshot-origin';\n\n/**\n * @internal\n */\nconst saveAlert = (event: BeforeUnloadEvent) => {\n  event.preventDefault();\n  return (event.returnValue =\n    'Data is not saved. Are you sure you want to leave?');\n};\n\nexport const writeOperation = async (op: Promise<unknown>) => {\n  window.addEventListener('beforeunload', saveAlert, {\n    capture: true,\n  });\n  await op;\n  window.removeEventListener('beforeunload', saveAlert, {\n    capture: true,\n  });\n};\n\nexport function revertUpdate(\n  doc: Doc,\n  snapshotUpdate: Uint8Array,\n  getMetadata: (key: string) => 'Text' | 'Map' | 'Array'\n) {\n  const snapshotDoc = new Doc();\n  applyUpdate(snapshotDoc, snapshotUpdate, snapshotOrigin);\n\n  const currentStateVector = encodeStateVector(doc);\n  const snapshotStateVector = encodeStateVector(snapshotDoc);\n\n  const changesSinceSnapshotUpdate = encodeStateAsUpdate(\n    doc,\n    snapshotStateVector\n  );\n  const undoManager = new UndoManager(\n    [...snapshotDoc.share.keys()].map(key => {\n      const type = getMetadata(key);\n      if (type === 'Text') {\n        return snapshotDoc.getText(key);\n      } else if (type === 'Map') {\n        return snapshotDoc.getMap(key);\n      } else if (type === 'Array') {\n        return snapshotDoc.getArray(key);\n      }\n      throw new Error('Unknown type');\n    }),\n    {\n      trackedOrigins: new Set([snapshotOrigin]),\n    }\n  );\n  applyUpdate(snapshotDoc, changesSinceSnapshotUpdate, snapshotOrigin);\n  undoManager.undo();\n  const revertChangesSinceSnapshotUpdate = encodeStateAsUpdate(\n    snapshotDoc,\n    currentStateVector\n  );\n  applyUpdate(doc, revertChangesSinceSnapshotUpdate, snapshotOrigin);\n}\n\nexport class EarlyDisconnectError extends Error {\n  constructor() {\n    super('Early disconnect');\n  }\n}\n\nexport class CleanupWhenConnectingError extends Error {\n  constructor() {\n    super('Cleanup when connecting');\n  }\n}\n\nexport const markMilestone = async (\n  id: string,\n  doc: Doc,\n  name: string,\n  dbName = DEFAULT_DB_NAME\n): Promise<void> => {\n  const dbPromise = openDB<BlockSuiteBinaryDB>(dbName, dbVersion, {\n    upgrade: upgradeDB,\n  });\n  const db = await dbPromise;\n  const store = db\n    .transaction('milestone', 'readwrite')\n    .objectStore('milestone');\n  const milestone = await store.get('id');\n  const binary = encodeStateAsUpdate(doc);\n  if (!milestone) {\n    await store.put({\n      id,\n      milestone: {\n        [name]: binary,\n      },\n    });\n  } else {\n    milestone.milestone[name] = binary;\n    await store.put(milestone);\n  }\n};\n\nexport const getMilestones = async (\n  id: string,\n  dbName: string = DEFAULT_DB_NAME\n): Promise<null | WorkspaceMilestone['milestone']> => {\n  const dbPromise = openDB<BlockSuiteBinaryDB>(dbName, dbVersion, {\n    upgrade: upgradeDB,\n  });\n  const db = await dbPromise;\n  const store = db\n    .transaction('milestone', 'readonly')\n    .objectStore('milestone');\n  const milestone = await store.get(id);\n  if (!milestone) {\n    return null;\n  }\n  return milestone.milestone;\n};\n\nexport * from './provider';\nexport * from './shared';\nexport * from './utils';\n"],"names":["dbVersion","DEFAULT_DB_NAME","upgradeDB","db","assertExists","val","message","allDb","mergeUpdates","updates","doc","Doc","update","applyUpdate","encodeStateAsUpdate","databaseExists","name","resolve","req","existed","tryMigrate","id","dbName","openDB","oldDB","workspaceTransaction","meta","version","downloadBinary","guid","overwriteBinary","pushBinary","t","mergeCount","setMergeCount","count","createIndexedDBDatasource","dbPromise","getDb","options","data","diffUpdate","encodeStateVectorFromUpdate","err","_a","store","rows","merged","writeOperation","createIndexedDBProvider","datasource","provider","apis","onStatusChange","createLazyProvider","snapshotOrigin","saveAlert","event","op","revertUpdate","snapshotUpdate","getMetadata","snapshotDoc","currentStateVector","encodeStateVector","snapshotStateVector","changesSinceSnapshotUpdate","undoManager","UndoManager","key","type","revertChangesSinceSnapshotUpdate","EarlyDisconnectError","CleanupWhenConnectingError","markMilestone","milestone","binary","getMilestones"],"mappings":"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","x_google_ignoreList":[1]}