@fluidframework/local-driver 3.0.2 → 3.2.0

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 +1 @@
1
- {"version":3,"file":"localSessionStorageDb.js","sourceRoot":"","sources":["../src/localSessionStorageDb.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { EventEmitter } from \"@fluid-internal/client-utils\";\nimport type { ICollection, IDb } from \"@fluidframework/server-services-core\";\nimport type { ITestDbFactory } from \"@fluidframework/server-test-utils\";\nimport { v4 as uuid } from \"uuid\";\n\n/**\n * A collection for local session storage, where data is stored in the browser\n * Functions include database operations such as queries, insertion and update.\n */\nclass LocalSessionStorageCollection<T> implements ICollection<T> {\n\t/**\n\t * @param collectionName - data type of the collection, e.g. blobs, deltas, trees, etc.\n\t */\n\tconstructor(private readonly collectionName: string) {}\n\n\tpublic aggregate(pipeline: any, options?: any): any {\n\t\tthrow new Error(\"Method Not Implemented\");\n\t}\n\n\tpublic async updateMany(filter: any, set: any, addToSet: any): Promise<void> {\n\t\tthrow new Error(\"Method Not Implemented\");\n\t}\n\tpublic async distinct(key: any, query: any): Promise<any> {\n\t\tthrow new Error(\"Method Not Implemented\");\n\t}\n\tpublic async findAndUpdate(query: any, value: T): Promise<{ value: T; existing: boolean }> {\n\t\tthrow new Error(\"Method not implemented.\");\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/server-services-core#ICollection.find}\n\t */\n\t/*\n\t * Each query key consists of several keys separated by '.' e.g: \"operation.sequenceNumber\".\n\t * The hierarchical syntax allows finding nested key patterns.\n\t */\n\tpublic async find(query: any, sort: any): Promise<any[]> {\n\t\t// split the keys and get the corresponding value\n\t\tfunction getValueByKey(propertyBag, key: string): any {\n\t\t\tconst keys = key.split(\".\");\n\t\t\tlet value = propertyBag;\n\t\t\tfor (const splitKey of keys) {\n\t\t\t\tvalue = value[splitKey];\n\t\t\t}\n\t\t\treturn value;\n\t\t}\n\n\t\t// getting keys of the query we are trying to find\n\t\tconst queryKeys = Object.keys(query);\n\t\tlet filteredCollection = this.getAllInternal();\n\t\tfor (const key of queryKeys) {\n\t\t\tif (!query[key]) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (query[key].$gt > 0 || query[key].$lt > 0) {\n\t\t\t\tif (query[key].$gt > 0) {\n\t\t\t\t\tfilteredCollection = filteredCollection.filter(\n\t\t\t\t\t\t(value) => getValueByKey(value, key) > query[key].$gt,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (query[key].$lt > 0) {\n\t\t\t\t\tfilteredCollection = filteredCollection.filter(\n\t\t\t\t\t\t(value) => getValueByKey(value, key) < query[key].$lt,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfilteredCollection = filteredCollection.filter(\n\t\t\t\t\t(value) => getValueByKey(value, key) === query[key],\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tif (sort && Object.keys(sort).length === 1) {\n\t\t\tfunction compare(a, b): number {\n\t\t\t\t// Non null asserting here because of the length check above\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tconst sortKey = Object.keys(sort)[0]!;\n\t\t\t\treturn sort[sortKey] === 1\n\t\t\t\t\t? getValueByKey(a, sortKey) - getValueByKey(b, sortKey)\n\t\t\t\t\t: getValueByKey(b, sortKey) - getValueByKey(a, sortKey);\n\t\t\t}\n\n\t\t\tfilteredCollection = filteredCollection.sort(compare);\n\t\t}\n\t\treturn filteredCollection;\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/server-services-core#ICollection.findAll}\n\t */\n\tpublic async findAll(): Promise<any[]> {\n\t\treturn this.getAllInternal();\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/server-services-core#ICollection.findOne}\n\t */\n\t/*\n\t * Query is expected to have a member \"_id\" which is a string used to find value in the database.\n\t */\n\tpublic async findOne(query: any): Promise<any> {\n\t\treturn this.findOneInternal(query);\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/server-services-core#ICollection.update}\n\t */\n\t/*\n\t * Query is expected to have a member \"_id\" which is a string used to find value in the database.\n\t */\n\tpublic async update(query: any, set: any, addToSet: any): Promise<void> {\n\t\tconst value = this.findOneInternal(query);\n\t\tif (value) {\n\t\t\tfor (const key of Object.keys(set)) {\n\t\t\t\tvalue[key] = set[key];\n\t\t\t}\n\t\t\tthis.insertInternal(value);\n\t\t} else {\n\t\t\tthrow new Error(\"Not found\");\n\t\t}\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/server-services-core#ICollection.upsert}\n\t */\n\t/*\n\t * Query is expected to have a member \"_id\" which is a string used to find value in the database.\n\t */\n\tpublic async upsert(query: any, set: any, addToSet: any): Promise<void> {\n\t\tconst value = this.findOneInternal(query);\n\t\tif (value) {\n\t\t\tfor (const key of Object.keys(set)) {\n\t\t\t\tvalue[key] = set[key];\n\t\t\t}\n\t\t\tthis.insertInternal(value);\n\t\t} else {\n\t\t\tthis.insertInternal(set);\n\t\t}\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/server-services-core#ICollection.insertOne}\n\t */\n\t/*\n\t * Value is expected to have a member \"_id\" which is a string used to search in the database.\n\t */\n\tpublic async insertOne(value: any): Promise<any> {\n\t\tconst presentVal = this.findOneInternal(value);\n\t\t// Only raise error when the object is present and the value is not equal.\n\t\tif (presentVal) {\n\t\t\tif (JSON.stringify(presentVal) === JSON.stringify(value)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthrow new Error(\"Existing Object!!\");\n\t\t}\n\n\t\treturn this.insertInternal(value);\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/server-services-core#ICollection.findOrCreate}\n\t */\n\t/*\n\t * Value and query are expected to have a member \"_id\" which is a string used to search or insert in the database.\n\t */\n\tpublic async findOrCreate(\n\t\tquery: any,\n\t\tvalue: any,\n\t): Promise<{ value: any; existing: boolean }> {\n\t\tconst existing = this.findOneInternal(query);\n\t\tif (existing) {\n\t\t\treturn { value: existing, existing: true };\n\t\t}\n\t\tthis.insertInternal(value);\n\t\treturn { value, existing: false };\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/server-services-core#ICollection.insertMany}\n\t */\n\t/*\n\t * Each element in values is expected to have a member \"_id\" which is a string used to insert in the database.\n\t */\n\tpublic async insertMany(values: any[], ordered: boolean): Promise<void> {\n\t\tthis.insertInternal(...values);\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/server-services-core#ICollection.deleteOne}\n\t */\n\tpublic async deleteOne(query: any): Promise<any> {\n\t\tthrow new Error(\"Method not implemented.\");\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/server-services-core#ICollection.deleteMany}\n\t */\n\tpublic async deleteMany(query: any): Promise<any> {\n\t\tthrow new Error(\"Method not implemented.\");\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/server-services-core#ICollection.createIndex}\n\t */\n\tpublic async createIndex(index: any, unique: boolean): Promise<void> {\n\t\tthrow new Error(\"Method not implemented.\");\n\t}\n\n\t/**\n\t * Return all values in the database\n\t */\n\tprivate getAllInternal(): any[] {\n\t\tconst values: string[] = [];\n\t\tfor (let i = 0; i < sessionStorage.length; i++) {\n\t\t\tconst key = sessionStorage.key(i);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tif (key!.startsWith(this.collectionName)) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tvalues.push(JSON.parse(sessionStorage.getItem(key!)!));\n\t\t\t}\n\t\t}\n\t\treturn values;\n\t}\n\n\t/**\n\t * Inserts values into the session storge.\n\t * Values are expected to have a member \"_id\" which is a unique id, otherwise will be assigned one\n\t *\n\t * @param values - data to insert to the database\n\t */\n\tprivate insertInternal(...values: any[]): void {\n\t\tfor (const value of values) {\n\t\t\tif (value) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- using ??= could change behavior if value is falsy\n\t\t\t\tif (!value._id) {\n\t\t\t\t\tvalue._id = uuid();\n\t\t\t\t}\n\t\t\t\tsessionStorage.setItem(`${this.collectionName}-${value._id}`, JSON.stringify(value));\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Finds the query in session storage and returns its value.\n\t * Returns null if query is not found.\n\t * Query is expected to have a member \"_id\" which is a unique id.\n\t *\n\t * @param query - what to find in the database\n\t */\n\tprivate findOneInternal(query: any): any {\n\t\tif (query._id) {\n\t\t\tconst json = sessionStorage.getItem(`${this.collectionName}-${query._id}`);\n\t\t\tif (json) {\n\t\t\t\treturn JSON.parse(json);\n\t\t\t}\n\t\t} else {\n\t\t\tconst queryKeys = Object.keys(query);\n\t\t\tfor (let i = 0; i < sessionStorage.length; i++) {\n\t\t\t\tconst ssKey = sessionStorage.key(i);\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tif (!ssKey!.startsWith(this.collectionName)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tconst value = JSON.parse(sessionStorage.getItem(ssKey!)!);\n\t\t\t\tlet foundMismatch = false;\n\t\t\t\tfor (const qk of queryKeys) {\n\t\t\t\t\tif (value[qk] !== query[qk]) {\n\t\t\t\t\t\tfoundMismatch = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!foundMismatch) {\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n}\n\n/**\n * A database for testing that stores data in the browsers session storage\n */\nclass LocalSessionStorageDb extends EventEmitter implements IDb {\n\tprivate readonly collections = new Map<string, LocalSessionStorageCollection<any>>();\n\tpublic async close(): Promise<void> {}\n\tpublic collection<T>(name: string): ICollection<T> {\n\t\tif (!this.collections.has(name)) {\n\t\t\tthis.collections.set(name, new LocalSessionStorageCollection<T>(name));\n\t\t}\n\t\treturn this.collections.get(name) as LocalSessionStorageCollection<T>;\n\t}\n\n\tpublic async dropCollection(name: string): Promise<boolean> {\n\t\tif (!this.collections.has(name)) {\n\t\t\treturn true;\n\t\t}\n\t\tthis.collections.delete(name);\n\t\treturn true;\n\t}\n}\n\n/**\n * A database factory for testing that stores data in the browsers session storage\n * @internal\n */\nexport class LocalSessionStorageDbFactory implements ITestDbFactory {\n\tpublic readonly testDatabase: IDb = new LocalSessionStorageDb();\n\tpublic async connect(): Promise<IDb> {\n\t\treturn this.testDatabase;\n\t}\n}\n"]}
1
+ {"version":3,"file":"localSessionStorageDb.js","sourceRoot":"","sources":["../src/localSessionStorageDb.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { EventEmitter } from \"@fluid-internal/client-utils\";\nimport type { ICollection, IDb } from \"@fluidframework/server-services-core\";\nimport type { ITestDbFactory } from \"@fluidframework/server-test-utils\";\nimport { v4 as uuid } from \"uuid\";\n\n/** Namespace for all session-storage records owned by local-driver. */\nconst sessionStorageKeyPrefix = \"@fluidframework/local-driver:\";\n\n/**\n * A collection for local session storage, where data is stored in the browser\n * Functions include database operations such as queries, insertion and update.\n */\nclass LocalSessionStorageCollection<T> implements ICollection<T> {\n\t/** Prefix that scopes session-storage records to this collection. */\n\tprivate readonly storageKeyPrefix: string;\n\n\t/**\n\t * @param collectionName - data type of the collection, e.g. blobs, deltas, trees, etc.\n\t */\n\tconstructor(collectionName: string) {\n\t\tthis.storageKeyPrefix = `${sessionStorageKeyPrefix}${collectionName}-`;\n\t}\n\n\tpublic aggregate(pipeline: any, options?: any): any {\n\t\tthrow new Error(\"Method Not Implemented\");\n\t}\n\n\tpublic async updateMany(filter: any, set: any, addToSet: any): Promise<void> {\n\t\tthrow new Error(\"Method Not Implemented\");\n\t}\n\tpublic async distinct(key: any, query: any): Promise<any> {\n\t\tthrow new Error(\"Method Not Implemented\");\n\t}\n\tpublic async findAndUpdate(query: any, value: T): Promise<{ value: T; existing: boolean }> {\n\t\tthrow new Error(\"Method not implemented.\");\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/server-services-core#ICollection.find}\n\t */\n\t/*\n\t * Each query key consists of several keys separated by '.' e.g: \"operation.sequenceNumber\".\n\t * The hierarchical syntax allows finding nested key patterns.\n\t */\n\tpublic async find(query: any, sort: any): Promise<any[]> {\n\t\t// split the keys and get the corresponding value\n\t\tfunction getValueByKey(propertyBag, key: string): any {\n\t\t\tconst keys = key.split(\".\");\n\t\t\tlet value = propertyBag;\n\t\t\tfor (const splitKey of keys) {\n\t\t\t\tvalue = value[splitKey];\n\t\t\t}\n\t\t\treturn value;\n\t\t}\n\n\t\t// getting keys of the query we are trying to find\n\t\tconst queryKeys = Object.keys(query);\n\t\tlet filteredCollection = this.getAllInternal();\n\t\tfor (const key of queryKeys) {\n\t\t\tif (!query[key]) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (query[key].$gt > 0 || query[key].$lt > 0) {\n\t\t\t\tif (query[key].$gt > 0) {\n\t\t\t\t\tfilteredCollection = filteredCollection.filter(\n\t\t\t\t\t\t(value) => getValueByKey(value, key) > query[key].$gt,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (query[key].$lt > 0) {\n\t\t\t\t\tfilteredCollection = filteredCollection.filter(\n\t\t\t\t\t\t(value) => getValueByKey(value, key) < query[key].$lt,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfilteredCollection = filteredCollection.filter(\n\t\t\t\t\t(value) => getValueByKey(value, key) === query[key],\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tif (sort && Object.keys(sort).length === 1) {\n\t\t\tfunction compare(a, b): number {\n\t\t\t\t// Non null asserting here because of the length check above\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tconst sortKey = Object.keys(sort)[0]!;\n\t\t\t\treturn sort[sortKey] === 1\n\t\t\t\t\t? getValueByKey(a, sortKey) - getValueByKey(b, sortKey)\n\t\t\t\t\t: getValueByKey(b, sortKey) - getValueByKey(a, sortKey);\n\t\t\t}\n\n\t\t\tfilteredCollection = filteredCollection.sort(compare);\n\t\t}\n\t\treturn filteredCollection;\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/server-services-core#ICollection.findAll}\n\t */\n\tpublic async findAll(): Promise<any[]> {\n\t\treturn this.getAllInternal();\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/server-services-core#ICollection.findOne}\n\t */\n\t/*\n\t * Query is expected to have a member \"_id\" which is a string used to find value in the database.\n\t */\n\tpublic async findOne(query: any): Promise<any> {\n\t\treturn this.findOneInternal(query);\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/server-services-core#ICollection.update}\n\t */\n\t/*\n\t * Query is expected to have a member \"_id\" which is a string used to find value in the database.\n\t */\n\tpublic async update(query: any, set: any, addToSet: any): Promise<void> {\n\t\tconst value = this.findOneInternal(query);\n\t\tif (value) {\n\t\t\tfor (const key of Object.keys(set)) {\n\t\t\t\tvalue[key] = set[key];\n\t\t\t}\n\t\t\tthis.insertInternal(value);\n\t\t} else {\n\t\t\tthrow new Error(\"Not found\");\n\t\t}\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/server-services-core#ICollection.upsert}\n\t */\n\t/*\n\t * Query is expected to have a member \"_id\" which is a string used to find value in the database.\n\t */\n\tpublic async upsert(query: any, set: any, addToSet: any): Promise<void> {\n\t\tconst value = this.findOneInternal(query);\n\t\tif (value) {\n\t\t\tfor (const key of Object.keys(set)) {\n\t\t\t\tvalue[key] = set[key];\n\t\t\t}\n\t\t\tthis.insertInternal(value);\n\t\t} else {\n\t\t\tthis.insertInternal(set);\n\t\t}\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/server-services-core#ICollection.insertOne}\n\t */\n\t/*\n\t * Value is expected to have a member \"_id\" which is a string used to search in the database.\n\t */\n\tpublic async insertOne(value: any): Promise<any> {\n\t\tconst presentVal = this.findOneInternal(value);\n\t\t// Only raise error when the object is present and the value is not equal.\n\t\tif (presentVal) {\n\t\t\tif (JSON.stringify(presentVal) === JSON.stringify(value)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthrow new Error(\"Existing Object!!\");\n\t\t}\n\n\t\treturn this.insertInternal(value);\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/server-services-core#ICollection.findOrCreate}\n\t */\n\t/*\n\t * Value and query are expected to have a member \"_id\" which is a string used to search or insert in the database.\n\t */\n\tpublic async findOrCreate(\n\t\tquery: any,\n\t\tvalue: any,\n\t): Promise<{ value: any; existing: boolean }> {\n\t\tconst existing = this.findOneInternal(query);\n\t\tif (existing) {\n\t\t\treturn { value: existing, existing: true };\n\t\t}\n\t\tthis.insertInternal(value);\n\t\treturn { value, existing: false };\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/server-services-core#ICollection.insertMany}\n\t */\n\t/*\n\t * Each element in values is expected to have a member \"_id\" which is a string used to insert in the database.\n\t */\n\tpublic async insertMany(values: any[], ordered: boolean): Promise<void> {\n\t\tthis.insertInternal(...values);\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/server-services-core#ICollection.deleteOne}\n\t */\n\tpublic async deleteOne(query: any): Promise<any> {\n\t\tconst value = this.findOneInternal(query);\n\t\tif (value !== null) {\n\t\t\tsessionStorage.removeItem(`${this.storageKeyPrefix}${value._id}`);\n\t\t}\n\t\treturn value;\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/server-services-core#ICollection.deleteMany}\n\t */\n\tpublic async deleteMany(query: any): Promise<any> {\n\t\tconst values = await this.find(query, undefined);\n\t\tfor (const value of values) {\n\t\t\tsessionStorage.removeItem(`${this.storageKeyPrefix}${value._id}`);\n\t\t}\n\t\treturn values;\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/server-services-core#ICollection.createIndex}\n\t */\n\tpublic async createIndex(index: any, unique: boolean): Promise<void> {\n\t\tthrow new Error(\"Method not implemented.\");\n\t}\n\n\t/**\n\t * Return all values in the database\n\t */\n\tprivate getAllInternal(): any[] {\n\t\tconst values: string[] = [];\n\t\tfor (let i = 0; i < sessionStorage.length; i++) {\n\t\t\tconst key = sessionStorage.key(i);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tif (key!.startsWith(this.storageKeyPrefix)) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tvalues.push(JSON.parse(sessionStorage.getItem(key!)!));\n\t\t\t}\n\t\t}\n\t\treturn values;\n\t}\n\n\t/**\n\t * Inserts values into the session storge.\n\t * Values are expected to have a member \"_id\" which is a unique id, otherwise will be assigned one\n\t *\n\t * @param values - data to insert to the database\n\t */\n\tprivate insertInternal(...values: any[]): void {\n\t\tfor (const value of values) {\n\t\t\tif (value) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- using ??= could change behavior if value is falsy\n\t\t\t\tif (!value._id) {\n\t\t\t\t\tvalue._id = uuid();\n\t\t\t\t}\n\t\t\t\tsessionStorage.setItem(`${this.storageKeyPrefix}${value._id}`, JSON.stringify(value));\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Finds the query in session storage and returns its value.\n\t * Returns null if query is not found.\n\t * Query is expected to have a member \"_id\" which is a unique id.\n\t *\n\t * @param query - what to find in the database\n\t */\n\tprivate findOneInternal(query: any): any {\n\t\tif (query._id) {\n\t\t\tconst json = sessionStorage.getItem(`${this.storageKeyPrefix}${query._id}`);\n\t\t\tif (json) {\n\t\t\t\treturn JSON.parse(json);\n\t\t\t}\n\t\t} else {\n\t\t\tconst queryKeys = Object.keys(query);\n\t\t\tfor (let i = 0; i < sessionStorage.length; i++) {\n\t\t\t\tconst ssKey = sessionStorage.key(i);\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tif (!ssKey!.startsWith(this.storageKeyPrefix)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tconst value = JSON.parse(sessionStorage.getItem(ssKey!)!);\n\t\t\t\tlet foundMismatch = false;\n\t\t\t\tfor (const qk of queryKeys) {\n\t\t\t\t\tif (value[qk] !== query[qk]) {\n\t\t\t\t\t\tfoundMismatch = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!foundMismatch) {\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n}\n\n/**\n * A database for testing that stores data in the browsers session storage\n */\nclass LocalSessionStorageDb extends EventEmitter implements IDb {\n\tprivate readonly collections = new Map<string, LocalSessionStorageCollection<any>>();\n\tpublic async close(): Promise<void> {}\n\tpublic collection<T>(name: string): ICollection<T> {\n\t\tif (!this.collections.has(name)) {\n\t\t\tthis.collections.set(name, new LocalSessionStorageCollection<T>(name));\n\t\t}\n\t\treturn this.collections.get(name) as LocalSessionStorageCollection<T>;\n\t}\n\n\tpublic async dropCollection(name: string): Promise<boolean> {\n\t\tif (!this.collections.has(name)) {\n\t\t\treturn true;\n\t\t}\n\t\tthis.collections.delete(name);\n\t\treturn true;\n\t}\n}\n\n/**\n * A database factory for testing that stores data in the browsers session storage\n * @internal\n */\nexport class LocalSessionStorageDbFactory implements ITestDbFactory {\n\tpublic readonly testDatabase: IDb = new LocalSessionStorageDb();\n\tpublic async connect(): Promise<IDb> {\n\t\treturn this.testDatabase;\n\t}\n}\n"]}
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export declare const pkgName = "@fluidframework/local-driver";
8
- export declare const pkgVersion = "3.0.2";
8
+ export declare const pkgVersion = "3.2.0";
9
9
  //# sourceMappingURL=packageVersion.d.ts.map
@@ -8,5 +8,5 @@
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.pkgVersion = exports.pkgName = void 0;
10
10
  exports.pkgName = "@fluidframework/local-driver";
11
- exports.pkgVersion = "3.0.2";
11
+ exports.pkgVersion = "3.2.0";
12
12
  //# sourceMappingURL=packageVersion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,8BAA8B,CAAC;AACzC,QAAA,UAAU,GAAG,OAAO,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/local-driver\";\nexport const pkgVersion = \"3.0.2\";\n"]}
1
+ {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,8BAA8B,CAAC;AACzC,QAAA,UAAU,GAAG,OAAO,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/local-driver\";\nexport const pkgVersion = \"3.2.0\";\n"]}
package/lib/alpha.d.ts CHANGED
@@ -11,9 +11,12 @@
11
11
  export {
12
12
  // #region @alpha APIs
13
13
  EphemeralService,
14
- EphemeralServiceClient,
14
+ LocalService,
15
+ LocalServiceClient,
16
+ SessionService,
15
17
  cleanupEphemeralService,
16
18
  getDefaultEphemeralService,
19
+ getSessionService,
17
20
  startEphemeralService
18
21
  // #endregion
19
22
  } from "./index.js";
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import type { IRequest } from "@fluidframework/core-interfaces";
6
6
  import { type ErasedBaseType } from "@fluidframework/core-interfaces/internal";
7
- import { type DataStoreKind, type DataStoreRegistry, type FluidContainerAttached, type FluidContainerWithService, type OldestSupportedServiceClientVersion, type ServiceClient, type ServiceOptions } from "@fluidframework/driver-definitions/internal";
7
+ import { type DataStoreKind, type DataStoreRegistry, type FluidContainerAttached, type FluidContainerWithService, type ServiceClient, type ServiceOptions } from "@fluidframework/driver-definitions/internal";
8
8
  import { ServiceContainerBase } from "@fluidframework/runtime-utils/internal";
9
9
  /**
10
10
  * Starts and returns a new {@link EphemeralService}.
@@ -18,6 +18,20 @@ import { ServiceContainerBase } from "@fluidframework/runtime-utils/internal";
18
18
  * @alpha
19
19
  */
20
20
  export declare function startEphemeralService(isDefault?: boolean): EphemeralService;
21
+ /**
22
+ * Gets the session-storage-backed local Fluid service for the current JavaScript realm, creating it on first use.
23
+ *
24
+ * @remarks
25
+ * Attached documents remain available after a page reload within the same browser tab. Repeated calls return
26
+ * the same service instance within the current JavaScript realm.
27
+ *
28
+ * This service is only available in browser environments that provide `sessionStorage`.
29
+ * @returns A local service backed by browser session storage.
30
+ * @alpha
31
+ */
32
+ export declare function getSessionService(): SessionService;
33
+ /** Closes and clears the current session service for test isolation. */
34
+ export declare function resetSessionServiceForTesting(): Promise<void>;
21
35
  /**
22
36
  * Cleans up the service passed in {@link startEphemeralService}, or the {@link getDefaultEphemeralService|default} if none is passed.
23
37
  * @remarks
@@ -34,23 +48,91 @@ export declare function cleanupEphemeralService(service?: EphemeralService): Pro
34
48
  */
35
49
  export declare function getDefaultEphemeralService(): EphemeralService;
36
50
  /**
37
- * Internal Options for creating an {@link EphemeralServiceClient}, extending {@link @fluidframework/driver-definitions#ServiceOptions}
38
- * with the {@link EphemeralService} the client should connect to.
51
+ * Internal options for creating a local service client, extending
52
+ * {@link @fluidframework/driver-definitions#ServiceOptions} with the service the client should connect to.
39
53
  * @input
40
54
  * @internal
41
55
  */
42
- export interface EphemeralServiceOptions extends ServiceOptions {
56
+ export interface LocalServiceOptions<TService extends LocalService = LocalService> extends ServiceOptions {
43
57
  /**
44
- * {@inheritdoc @fluidframework/driver-definitions#ServiceOptions.oldestSupportedClient}
58
+ * The service instance to connect to.
45
59
  */
46
- readonly oldestSupportedClient: OldestSupportedServiceClientVersion;
60
+ readonly service: TService;
61
+ }
62
+ /**
63
+ * Internal options for creating a {@link LocalServiceClient} connected to an {@link EphemeralService}.
64
+ * @input
65
+ * @internal
66
+ */
67
+ export interface EphemeralServiceOptions extends LocalServiceOptions<EphemeralService> {
68
+ }
69
+ /**
70
+ * A local Fluid service with an explicitly managed lifecycle.
71
+ * @remarks
72
+ * There are two implementations of this interface with different document lifetimes:
73
+ * {@link EphemeralService} and {@link SessionService}.
74
+ *
75
+ * @typeParam TClient - The type of client this service creates.
76
+ * @alpha @sealed
77
+ */
78
+ export interface LocalService<out TClient extends ServiceClient = LocalServiceClient> extends ErasedBaseType<readonly ["LocalService", TClient]> {
47
79
  /**
48
- * The service instance to connect to.
80
+ * Lists the IDs of documents currently stored by this service.
81
+ */
82
+ listDocumentIds(): Promise<readonly string[]>;
83
+ /**
84
+ * Deletes a stored document.
85
+ *
86
+ * @remarks
87
+ * Deletion is only allowed when this service has no open containers because resetting the local
88
+ * server invalidates all of its active connections. Content-addressed summary data shared with other
89
+ * documents may be retained until {@link LocalService.deleteAllDocuments} is called.
90
+ * Only one call to {@link LocalService.deleteDocument} or {@link LocalService.deleteAllDocuments}
91
+ * may be in progress at a time.
92
+ *
93
+ * @param id - The ID of the document to delete.
94
+ * @throws A `UsageError` if the service is closed, another document deletion is in progress, or the
95
+ * service has open containers.
96
+ */
97
+ deleteDocument(id: string): Promise<void>;
98
+ /**
99
+ * Deletes all documents stored by this service.
100
+ *
101
+ * @remarks
102
+ * Deletion is only allowed when this service has no open containers because resetting the local
103
+ * server invalidates all of its active connections.
104
+ * Only one call to {@link LocalService.deleteDocument} or {@link LocalService.deleteAllDocuments}
105
+ * may be in progress at a time.
106
+ * @throws A `UsageError` if the service is closed, another document deletion is in progress, or the
107
+ * service has open containers.
108
+ */
109
+ deleteAllDocuments(): Promise<void>;
110
+ /**
111
+ * Drives all containers connected to this service toward convergence, processing pending operations and
112
+ * waiting for all dirty containers to save.
113
+ *
114
+ * @param timeoutMilliseconds - The maximum time to wait for containers to quiesce, in milliseconds. Defaults to 30_000.
115
+ * @throws A `UsageError` if the containers do not quiesce before the timeout expires.
116
+ *
117
+ * @privateRemarks
118
+ * This is a best-effort implementation simplified from `LoaderContainerTracker.ensureSynchronized`.
119
+ * Currently it does not perform receiver-side sequence-number quiescence or wait for join/leave (audience) ops.
120
+ * See `LoaderContainerTracker.ensureSynchronized` for the fuller version this is based on.
121
+ */
122
+ synchronize(timeoutMilliseconds?: number): Promise<void>;
123
+ /**
124
+ * Creates a client connected to this service.
125
+ *
126
+ * @param options - Collaboration options for the client.
127
+ */
128
+ newClient(options: ServiceOptions): TClient;
129
+ /**
130
+ * A client connected to this service using the default options.
49
131
  */
50
- readonly service: EphemeralService;
132
+ readonly defaultClient: TClient;
51
133
  }
52
134
  /**
53
- * An in-memory Fluid service that can produce connected {@link EphemeralServiceClient}s.
135
+ * An in-memory Fluid service that can produce connected {@link LocalServiceClient}s.
54
136
  * @remarks
55
137
  * All documents created through clients connected to a given `EphemeralService` are held in-memory by that service.
56
138
  * Closing the service (via {@link EphemeralService.close} or {@link cleanupEphemeralService}) closes the connections
@@ -68,20 +150,20 @@ export interface EphemeralServiceOptions extends ServiceOptions {
68
150
  * document with different `oldestSupportedClient` values.
69
151
  * This also exposes a place to put APIs for preloading and exporting document contents in the future.
70
152
  *
71
- * This is an erased type: its only implementation is the module-private {@link EphemeralServiceImplementation}, which holds
153
+ * This is an erased type: its only implementation is the module-private `LocalServiceImplementation`, which holds
72
154
  * the mutable server and container state so it does not appear on this public type.
73
155
  *
74
156
  * TODO: formalize this lifecycle with an interface which documents these stages.
75
157
  * Lifecycle:
76
158
  * The intended lifecycle of an {@link EphemeralService} follows roughly the same pattern as containers:
77
159
  *
78
- * 1. Open: accepts connections from {@link EphemeralServiceClient}s, which can create and load containers.
160
+ * 1. Open: accepts connections from {@link LocalServiceClient}s, which can create and load containers.
79
161
  * Might have timers and event registrations which can trigger asynchronous work, and retain the object in memory.
80
162
  *
81
163
  * 2. Closing: asynchronous transition from open to closed. New use should behave as it closed, but may be cleaning up or saving resources asynchronously.
82
164
  * Timers and event registrations may still be active, but should be cleaned up by the time the transition to closed completes.
83
165
  *
84
- * 3. Closed: no longer accepts connections from {@link EphemeralServiceClient}s, and all containers connected to it are closed.
166
+ * 3. Closed: no longer accepts connections from {@link LocalServiceClient}s, and all containers connected to it are closed.
85
167
  * Should have no subscriptions to events or timers which could retain it in memory or trigger asynchronous work.
86
168
  * The object can still be used in a limited capacity (typically just to inspect its status (e.g. `isClosed`), and to view (but not edit) the final state of any containers which were connected to it before it closed.)
87
169
  *
@@ -90,75 +172,45 @@ export interface EphemeralServiceOptions extends ServiceOptions {
90
172
  *
91
173
  * @alpha @sealed
92
174
  */
93
- export interface EphemeralService extends ErasedBaseType<readonly ["EphemeralService"]> {
94
- /**
95
- * Close this service, which closes all containers connected to it and releases its resources.
96
- * @remarks
97
- * All documents held by this service are discarded, and any timers it (or its containers) were keeping alive
98
- * are cleaned up.
99
- * The returned promise resolves once all asynchronous cleanup (including shutting down the in-memory server)
100
- * has completed.
101
- * Closing is idempotent: calling it again after the service is closed resolves without doing anything.
102
- */
103
- close(): Promise<void>;
104
- /**
105
- * Drives all containers connected to this service toward convergence, processing pending operations and
106
- * waiting for all dirty containers to save.
107
- *
108
- * @param timeoutMilliseconds - The maximum time to wait for containers to quiesce, in milliseconds. Defaults to 30_000.
109
- *
110
- * @privateRemarks
111
- * This is a best-effort implementation simplified from `LoaderContainerTracker.ensureSynchronized`.
112
- * Currently it does not perform receiver-side sequence-number quiescence or wait for join/leave (audience) ops.
113
- * See `LoaderContainerTracker.ensureSynchronized` for the fuller version this is based on.
114
- * For the currently exposed API surface, this should be sufficient,
115
- * but users down casting to internal types might run into some limitations.
116
- */
117
- synchronize(timeoutMilliseconds?: number): Promise<void>;
175
+ export interface EphemeralService extends LocalService<LocalServiceClient<EphemeralService>> {
118
176
  /**
119
- * Creates and returns a {@link EphemeralServiceClient} for an in-memory, ephemeral Fluid service.
120
- *
121
- * @param options - Options for the client. `oldestSupportedClient` may be omitted because all
122
- * clients are in the same process, so it defaults to the current version. `service` may be omitted to allocate a new
123
- * {@link EphemeralService} dedicated to this client, or provided to connect the client to an existing service instance.
177
+ * Closes all containers connected to this service and releases its active resources.
124
178
  *
125
179
  * @remarks
126
- * The service is ephemeral and in-memory: all documents are held by the {@link EphemeralService} the client is
127
- * connected to, and live for as long as that service is open — independent of whether any container for them is open.
128
- * A document created and attached (obtaining an `id`) can be loaded by `id` for as long as its service remains open,
129
- * even after every container for it has been closed.
130
- * Closing the service (via {@link EphemeralService.close} or {@link cleanupEphemeralService}) discards all of its
131
- * documents and releases its resources; afterwards those `id`s can no longer be loaded.
132
- *
133
- * When no `service` is provided, a new one is allocated for this client (accessible via {@link EphemeralServiceClient.service}).
134
- * Provide the same {@link EphemeralService} to multiple clients (via `options.service`) to have them collaborate on the
135
- * same documents, and control that service's lifetime explicitly.
136
- *
137
- * Since a service holds timers while open, tests should close the services they use (e.g. via
138
- * {@link cleanupEphemeralService} in an `afterEach`) to avoid lingering timers that can hang test runners.
139
- *
140
- * @privateRemarks
141
- * TODO: We should provide a way to extract (for potential serialization as test data) and load documents into a service.
142
- * This is needed to use this API surface for testing reference documents.
143
- * Ideally we would provide a service agnostic way to do the export, but likely only support loading them into the local service.
144
- * This can be done via an API on FluidContainer (or a free function taking one) to do the export, then adding a
145
- * service specific API (on {@link EphemeralService}) to load from the export format and return the ID of the loaded document.
146
- */
147
- newClient(options: ServiceOptions): EphemeralServiceClient;
148
- /**
149
- * A client connected to this service using the default options.
180
+ * Closing is idempotent. Closing an ephemeral service permanently discards all documents it holds,
181
+ * so their IDs can no longer be loaded.
150
182
  */
151
- readonly defaultClient: EphemeralServiceClient;
183
+ close(): Promise<void>;
184
+ }
185
+ /**
186
+ * A browser-local Fluid service that persists documents in session storage.
187
+ *
188
+ * @remarks
189
+ * Its attached documents remain available after a page reload within the same browser tab. The service is
190
+ * shared within the current JavaScript realm and intentionally has no close operation: its active resources
191
+ * live until the realm is unloaded.
192
+ *
193
+ * Session storage is shared more broadly than JavaScript module state. Separate same-origin realms, such as
194
+ * same-origin frames, or applications that load separate copies of this package can access the same stored
195
+ * documents while running independent local servers. Concurrently editing the same document from such realms
196
+ * is unsupported and may produce inconsistent stored state.
197
+ *
198
+ * Create one with {@link getSessionService}.
199
+ * @alpha @sealed
200
+ */
201
+ export interface SessionService extends LocalService<LocalServiceClient<SessionService>> {
152
202
  }
153
203
  /**
154
- * A {@link @fluidframework/driver-definitions#ServiceClient} connected to a specific {@link EphemeralService}.
204
+ * A {@link @fluidframework/driver-definitions#ServiceClient} connected to a specific {@link LocalService}.
205
+ *
206
+ * @typeParam TService - The type of local service this client is connected to.
155
207
  * @alpha @sealed
156
208
  */
157
- export interface EphemeralServiceClient extends ServiceClient {
209
+ export interface LocalServiceClient<out TService extends LocalService<ServiceClient> = LocalService<ServiceClient>> extends ServiceClient {
158
210
  /**
159
211
  * The service instance this client is connected to.
160
212
  */
161
- readonly service: EphemeralService;
213
+ readonly service: TService;
162
214
  }
163
215
  /**
164
216
  * A Fluid container backed by an ephemeral (in-memory) local service, implementing
@@ -170,10 +222,10 @@ export interface EphemeralServiceClient extends ServiceClient {
170
222
  *
171
223
  * @internal
172
224
  */
173
- export declare class EphemeralServiceContainer<TData> extends ServiceContainerBase<TData, EphemeralServiceOptions> implements FluidContainerWithService<TData> {
174
- readonly service: EphemeralService;
175
- static createDetached<T>(registry: DataStoreRegistry<T>, options: EphemeralServiceOptions, root: DataStoreKind<T>): Promise<EphemeralServiceContainer<T>>;
176
- static load<T>(registry: DataStoreRegistry<T>, options: EphemeralServiceOptions, id: string): Promise<EphemeralServiceContainer<T> & FluidContainerAttached<T>>;
225
+ export declare class EphemeralServiceContainer<TData> extends ServiceContainerBase<TData, LocalServiceOptions> implements FluidContainerWithService<TData> {
226
+ readonly service: LocalService;
227
+ static createDetached<T>(registry: DataStoreRegistry<T>, options: LocalServiceOptions, root: DataStoreKind<T>): Promise<EphemeralServiceContainer<T>>;
228
+ static load<T>(registry: DataStoreRegistry<T>, options: LocalServiceOptions, id: string): Promise<EphemeralServiceContainer<T> & FluidContainerAttached<T>>;
177
229
  private constructor();
178
230
  close(): void;
179
231
  protected createAttachRequest(): IRequest;
@@ -1 +1 @@
1
- {"version":3,"file":"ephemeralService.d.ts","sourceRoot":"","sources":["../src/ephemeralService.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAEN,KAAK,cAAc,EACnB,MAAM,0CAA0C,CAAC;AAElD,OAAO,EAEN,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,yBAAyB,EAC9B,KAAK,mCAAmC,EAExC,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,MAAM,6CAA6C,CAAC;AACrD,OAAO,EAMN,oBAAoB,EACpB,MAAM,wCAAwC,CAAC;AAWhD;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,UAAO,GAAG,gBAAgB,CAUxE;AAED;;;;;;;GAOG;AACH,wBAAsB,uBAAuB,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CASvF;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,IAAI,gBAAgB,CAK7D;AAED;;;;;GAKG;AACH,MAAM,WAAW,uBAAwB,SAAQ,cAAc;IAC9D;;OAEG;IACH,QAAQ,CAAC,qBAAqB,EAAE,mCAAmC,CAAC;IACpE;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,gBAAgB,CAAC;CACnC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,MAAM,WAAW,gBAAiB,SAAQ,cAAc,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;IACtF;;;;;;;;OAQG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;;;;;;;;;;;OAYG;IACH,WAAW,CAAC,mBAAmB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,sBAAsB,CAAC;IAE3D;;OAEG;IACH,QAAQ,CAAC,aAAa,EAAE,sBAAsB,CAAC;CAC/C;AAyKD;;;GAGG;AACH,MAAM,WAAW,sBAAuB,SAAQ,aAAa;IAC5D;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,gBAAgB,CAAC;CACnC;AAuDD;;;;;;;;;GASG;AACH,qBAAa,yBAAyB,CAAC,KAAK,CAC3C,SAAQ,oBAAoB,CAAC,KAAK,EAAE,uBAAuB,CAC3D,YAAW,yBAAyB,CAAC,KAAK,CAAC;IAE3C,SAAgB,OAAO,EAAE,gBAAgB,CAAC;WAEtB,cAAc,CAAC,CAAC,EACnC,QAAQ,EAAE,iBAAiB,CAAC,CAAC,CAAC,EAC9B,OAAO,EAAE,uBAAuB,EAChC,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,GACpB,OAAO,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC;WAuBpB,IAAI,CAAC,CAAC,EACzB,QAAQ,EAAE,iBAAiB,CAAC,CAAC,CAAC,EAC9B,OAAO,EAAE,uBAAuB,EAChC,EAAE,EAAE,MAAM,GACR,OAAO,CAAC,yBAAyB,CAAC,CAAC,CAAC,GAAG,sBAAsB,CAAC,CAAC,CAAC,CAAC;IA2BpE,OAAO;IAaS,KAAK,IAAI,IAAI;IAO7B,SAAS,CAAC,mBAAmB,IAAI,QAAQ;CAIzC"}
1
+ {"version":3,"file":"ephemeralService.d.ts","sourceRoot":"","sources":["../src/ephemeralService.ts"],"names":[],"mappings":"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"}