@milaboratories/pf-driver 1.2.0 → 1.3.1

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.
@@ -87,6 +87,7 @@ var RemoteBlobProviderImpl = class RemoteBlobProviderImpl {
87
87
  }
88
88
  async [Symbol.asyncDispose]() {
89
89
  await this.server.stop();
90
+ await this.pool[Symbol.asyncDispose]();
90
91
  }
91
92
  };
92
93
  async function createPFrameDriverDouble({ dataFolder = (0, node_os.tmpdir)(), logger = console.log }) {
@@ -1 +1 @@
1
- {"version":3,"file":"driver_double.cjs","names":["fs","PFrameDriverError","RefCountPoolBase","path","HttpHelpers","PFrameInternal","makeJsonDataInfo","AbstractPFrameDriver"],"sources":["../src/driver_double.ts"],"sourcesContent":["import {\n isDataInfo,\n PFrameDriverError,\n type Branded,\n type PColumnSpec,\n type PColumnValues,\n} from \"@milaboratories/pl-model-common\";\nimport { PFrameInternal } from \"@milaboratories/pl-model-middle-layer\";\nimport { RefCountPoolBase, type PoolEntry } from \"@milaboratories/ts-helpers\";\nimport { HttpHelpers } from \"@milaboratories/pframes-rs-node\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { tmpdir } from \"node:os\";\nimport type { AbstractInternalPFrameDriver } from \"./driver_decl\";\nimport {\n AbstractPFrameDriver,\n type LocalBlobProvider,\n type RemoteBlobProvider,\n} from \"./driver_impl\";\nimport { makeJsonDataInfo } from \"./data_info_helpers\";\n\nexport type FileName = Branded<string, \"FileName\">;\nexport type FilePath = Branded<string, \"FilePath\">;\nexport type FolderPath = Branded<string, \"FolderPath\">;\n\nexport function makeFolderPath(dataFolder: string): FolderPath {\n if (!fs.statSync(dataFolder, { throwIfNoEntry: false })?.isDirectory()) {\n const error = new PFrameDriverError(`Invalid data folder`);\n error.cause = new Error(`Folder ${dataFolder} does not exist`);\n throw error;\n }\n return dataFolder as FolderPath;\n}\n\nfunction makeBlobId(res: FileName): PFrameInternal.PFrameBlobId {\n return res as string as PFrameInternal.PFrameBlobId;\n}\n\nclass LocalBlobProviderImpl\n extends RefCountPoolBase<FileName, PFrameInternal.PFrameBlobId, FilePath>\n implements LocalBlobProvider<FileName>\n{\n constructor(private readonly dataFolder: FolderPath) {\n super();\n }\n\n protected calculateParamsKey(params: FileName): PFrameInternal.PFrameBlobId {\n return makeBlobId(params);\n }\n\n protected createNewResource(params: FileName, _key: PFrameInternal.PFrameBlobId): FilePath {\n const filePath = path.join(this.dataFolder, params);\n if (!fs.statSync(filePath, { throwIfNoEntry: false })?.isFile()) {\n const error = new PFrameDriverError(`Invalid file name`);\n error.cause = new Error(`File ${filePath} does not exist`);\n throw error;\n }\n return filePath as FilePath;\n }\n\n public getByKey(blobId: PFrameInternal.PFrameBlobId): FilePath {\n const resource = super.tryGetByKey(blobId);\n if (!resource) {\n const error = new PFrameDriverError(`Invalid blob id`);\n error.cause = new Error(`Blob with id ${blobId} not found.`);\n throw error;\n }\n return resource;\n }\n\n public makeDataSource(\n signal: AbortSignal,\n ): Omit<PFrameInternal.PFrameDataSourceV2, \"parquetServer\"> {\n return {\n preloadBlob: async (_blobIds: PFrameInternal.PFrameBlobId[]) => {},\n resolveBlobContent: async (blobId: PFrameInternal.PFrameBlobId) => {\n const filePath = this.getByKey(blobId);\n return await fs.promises.readFile(filePath, { signal });\n },\n };\n }\n}\n\nclass RemoteBlobProviderImpl implements RemoteBlobProvider<FileName> {\n constructor(\n private readonly pool: LocalBlobProviderImpl,\n private readonly server: PFrameInternal.HttpServer,\n ) {}\n\n public static async init(\n dataFolder: FolderPath,\n logger: PFrameInternal.Logger,\n serverOptions: Omit<PFrameInternal.HttpServerOptions, \"handler\">,\n ): Promise<RemoteBlobProviderImpl> {\n const pool = new LocalBlobProviderImpl(dataFolder);\n\n const underlyingStore = await HttpHelpers.createFsStore({ rootDir: dataFolder, logger });\n const store: PFrameInternal.ObjectStore = {\n request: (filename, params) => {\n const blobId = filename.slice(0, -PFrameInternal.ParquetExtension.length);\n return underlyingStore.request(blobId as PFrameInternal.ParquetFileName, params);\n },\n };\n\n const handler = HttpHelpers.createRequestHandler({ store });\n const server = await HttpHelpers.createHttpServer({ ...serverOptions, handler });\n\n return new RemoteBlobProviderImpl(pool, server);\n }\n\n public acquire(params: FileName): PoolEntry<PFrameInternal.PFrameBlobId> {\n return this.pool.acquire(params);\n }\n\n public httpServerInfo(): PFrameInternal.HttpServerInfo {\n return this.server.info;\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n await this.server.stop();\n }\n}\n\nexport type InternalPFrameDriverDouble = AbstractInternalPFrameDriver<\n PFrameInternal.DataInfo<FileName> | PColumnValues\n>;\n\n// It's mock for testing purposes, not a real test!\nexport async function createPFrameDriverDouble({\n dataFolder = tmpdir() as FolderPath,\n logger = console.log,\n}: {\n dataFolder?: FolderPath;\n logger?: PFrameInternal.Logger;\n}): Promise<InternalPFrameDriverDouble> {\n const localBlobProvider = new LocalBlobProviderImpl(dataFolder);\n const remoteBlobProvider = await RemoteBlobProviderImpl.init(dataFolder, logger, {});\n\n const resolveDataInfo = (\n spec: PColumnSpec,\n data: PFrameInternal.DataInfo<FileName> | PColumnValues,\n ) => (isDataInfo(data) ? data : makeJsonDataInfo(spec, data));\n\n return new AbstractPFrameDriver({\n logger,\n localBlobProvider,\n remoteBlobProvider,\n resolveDataInfo,\n });\n}\n"],"mappings":";;;;;;;;;;;;;;AAyBA,SAAgB,eAAe,YAAgC;AAC7D,KAAI,CAACA,gBAAG,SAAS,YAAY,EAAE,gBAAgB,OAAO,CAAC,EAAE,aAAa,EAAE;EACtE,MAAM,QAAQ,IAAIC,kDAAkB,sBAAsB;AAC1D,QAAM,wBAAQ,IAAI,MAAM,UAAU,WAAW,iBAAiB;AAC9D,QAAM;;AAER,QAAO;;AAGT,SAAS,WAAW,KAA4C;AAC9D,QAAO;;AAGT,IAAM,wBAAN,cACUC,4CAEV;CACE,YAAY,AAAiB,YAAwB;AACnD,SAAO;EADoB;;CAI7B,AAAU,mBAAmB,QAA+C;AAC1E,SAAO,WAAW,OAAO;;CAG3B,AAAU,kBAAkB,QAAkB,MAA6C;EACzF,MAAM,WAAWC,kBAAK,KAAK,KAAK,YAAY,OAAO;AACnD,MAAI,CAACH,gBAAG,SAAS,UAAU,EAAE,gBAAgB,OAAO,CAAC,EAAE,QAAQ,EAAE;GAC/D,MAAM,QAAQ,IAAIC,kDAAkB,oBAAoB;AACxD,SAAM,wBAAQ,IAAI,MAAM,QAAQ,SAAS,iBAAiB;AAC1D,SAAM;;AAER,SAAO;;CAGT,AAAO,SAAS,QAA+C;EAC7D,MAAM,WAAW,MAAM,YAAY,OAAO;AAC1C,MAAI,CAAC,UAAU;GACb,MAAM,QAAQ,IAAIA,kDAAkB,kBAAkB;AACtD,SAAM,wBAAQ,IAAI,MAAM,gBAAgB,OAAO,aAAa;AAC5D,SAAM;;AAER,SAAO;;CAGT,AAAO,eACL,QAC0D;AAC1D,SAAO;GACL,aAAa,OAAO,aAA4C;GAChE,oBAAoB,OAAO,WAAwC;IACjE,MAAM,WAAW,KAAK,SAAS,OAAO;AACtC,WAAO,MAAMD,gBAAG,SAAS,SAAS,UAAU,EAAE,QAAQ,CAAC;;GAE1D;;;AAIL,IAAM,yBAAN,MAAM,uBAA+D;CACnE,YACE,AAAiB,MACjB,AAAiB,QACjB;EAFiB;EACA;;CAGnB,aAAoB,KAClB,YACA,QACA,eACiC;EACjC,MAAM,OAAO,IAAI,sBAAsB,WAAW;EAElD,MAAM,kBAAkB,MAAMI,4CAAY,cAAc;GAAE,SAAS;GAAY;GAAQ,CAAC;EAQxF,MAAM,UAAUA,4CAAY,qBAAqB,EAAE,OAPT,EACxC,UAAU,UAAU,WAAW;GAC7B,MAAM,SAAS,SAAS,MAAM,GAAG,CAACC,qDAAe,iBAAiB,OAAO;AACzE,UAAO,gBAAgB,QAAQ,QAA0C,OAAO;KAEnF,EAEyD,CAAC;AAG3D,SAAO,IAAI,uBAAuB,MAFnB,MAAMD,4CAAY,iBAAiB;GAAE,GAAG;GAAe;GAAS,CAAC,CAEjC;;CAGjD,AAAO,QAAQ,QAA0D;AACvE,SAAO,KAAK,KAAK,QAAQ,OAAO;;CAGlC,AAAO,iBAAgD;AACrD,SAAO,KAAK,OAAO;;CAGrB,OAAO,OAAO,gBAA+B;AAC3C,QAAM,KAAK,OAAO,MAAM;;;AAS5B,eAAsB,yBAAyB,EAC7C,kCAAqB,EACrB,SAAS,QAAQ,OAIqB;CACtC,MAAM,oBAAoB,IAAI,sBAAsB,WAAW;CAC/D,MAAM,qBAAqB,MAAM,uBAAuB,KAAK,YAAY,QAAQ,EAAE,CAAC;CAEpF,MAAM,mBACJ,MACA,yDACe,KAAK,GAAG,OAAOE,2CAAiB,MAAM,KAAK;AAE5D,QAAO,IAAIC,yCAAqB;EAC9B;EACA;EACA;EACA;EACD,CAAC"}
1
+ {"version":3,"file":"driver_double.cjs","names":["fs","PFrameDriverError","RefCountPoolBase","path","HttpHelpers","PFrameInternal","makeJsonDataInfo","AbstractPFrameDriver"],"sources":["../src/driver_double.ts"],"sourcesContent":["import {\n isDataInfo,\n PFrameDriverError,\n type Branded,\n type PColumnSpec,\n type PColumnValues,\n} from \"@milaboratories/pl-model-common\";\nimport { PFrameInternal } from \"@milaboratories/pl-model-middle-layer\";\nimport { RefCountPoolBase, type PoolEntry } from \"@milaboratories/ts-helpers\";\nimport { HttpHelpers } from \"@milaboratories/pframes-rs-node\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { tmpdir } from \"node:os\";\nimport type { AbstractInternalPFrameDriver } from \"./driver_decl\";\nimport {\n AbstractPFrameDriver,\n type LocalBlobProvider,\n type RemoteBlobProvider,\n} from \"./driver_impl\";\nimport { makeJsonDataInfo } from \"./data_info_helpers\";\n\nexport type FileName = Branded<string, \"FileName\">;\nexport type FilePath = Branded<string, \"FilePath\">;\nexport type FolderPath = Branded<string, \"FolderPath\">;\n\nexport function makeFolderPath(dataFolder: string): FolderPath {\n if (!fs.statSync(dataFolder, { throwIfNoEntry: false })?.isDirectory()) {\n const error = new PFrameDriverError(`Invalid data folder`);\n error.cause = new Error(`Folder ${dataFolder} does not exist`);\n throw error;\n }\n return dataFolder as FolderPath;\n}\n\nfunction makeBlobId(res: FileName): PFrameInternal.PFrameBlobId {\n return res as string as PFrameInternal.PFrameBlobId;\n}\n\nclass LocalBlobProviderImpl\n extends RefCountPoolBase<FileName, PFrameInternal.PFrameBlobId, FilePath>\n implements LocalBlobProvider<FileName>\n{\n constructor(private readonly dataFolder: FolderPath) {\n super();\n }\n\n protected calculateParamsKey(params: FileName): PFrameInternal.PFrameBlobId {\n return makeBlobId(params);\n }\n\n protected createNewResource(params: FileName, _key: PFrameInternal.PFrameBlobId): FilePath {\n const filePath = path.join(this.dataFolder, params);\n if (!fs.statSync(filePath, { throwIfNoEntry: false })?.isFile()) {\n const error = new PFrameDriverError(`Invalid file name`);\n error.cause = new Error(`File ${filePath} does not exist`);\n throw error;\n }\n return filePath as FilePath;\n }\n\n public getByKey(blobId: PFrameInternal.PFrameBlobId): FilePath {\n const resource = super.tryGetByKey(blobId);\n if (!resource) {\n const error = new PFrameDriverError(`Invalid blob id`);\n error.cause = new Error(`Blob with id ${blobId} not found.`);\n throw error;\n }\n return resource;\n }\n\n public makeDataSource(\n signal: AbortSignal,\n ): Omit<PFrameInternal.PFrameDataSourceV2, \"parquetServer\"> {\n return {\n preloadBlob: async (_blobIds: PFrameInternal.PFrameBlobId[]) => {},\n resolveBlobContent: async (blobId: PFrameInternal.PFrameBlobId) => {\n const filePath = this.getByKey(blobId);\n return await fs.promises.readFile(filePath, { signal });\n },\n };\n }\n}\n\nclass RemoteBlobProviderImpl implements RemoteBlobProvider<FileName> {\n constructor(\n private readonly pool: LocalBlobProviderImpl,\n private readonly server: PFrameInternal.HttpServer,\n ) {}\n\n public static async init(\n dataFolder: FolderPath,\n logger: PFrameInternal.Logger,\n serverOptions: Omit<PFrameInternal.HttpServerOptions, \"handler\">,\n ): Promise<RemoteBlobProviderImpl> {\n const pool = new LocalBlobProviderImpl(dataFolder);\n\n const underlyingStore = await HttpHelpers.createFsStore({ rootDir: dataFolder, logger });\n const store: PFrameInternal.ObjectStore = {\n request: (filename, params) => {\n const blobId = filename.slice(0, -PFrameInternal.ParquetExtension.length);\n return underlyingStore.request(blobId as PFrameInternal.ParquetFileName, params);\n },\n };\n\n const handler = HttpHelpers.createRequestHandler({ store });\n const server = await HttpHelpers.createHttpServer({ ...serverOptions, handler });\n\n return new RemoteBlobProviderImpl(pool, server);\n }\n\n public acquire(params: FileName): PoolEntry<PFrameInternal.PFrameBlobId> {\n return this.pool.acquire(params);\n }\n\n public httpServerInfo(): PFrameInternal.HttpServerInfo {\n return this.server.info;\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n await this.server.stop();\n await this.pool[Symbol.asyncDispose]();\n }\n}\n\nexport type InternalPFrameDriverDouble = AbstractInternalPFrameDriver<\n PFrameInternal.DataInfo<FileName> | PColumnValues\n>;\n\n// It's mock for testing purposes, not a real test!\nexport async function createPFrameDriverDouble({\n dataFolder = tmpdir() as FolderPath,\n logger = console.log,\n}: {\n dataFolder?: FolderPath;\n logger?: PFrameInternal.Logger;\n}): Promise<InternalPFrameDriverDouble> {\n const localBlobProvider = new LocalBlobProviderImpl(dataFolder);\n const remoteBlobProvider = await RemoteBlobProviderImpl.init(dataFolder, logger, {});\n\n const resolveDataInfo = (\n spec: PColumnSpec,\n data: PFrameInternal.DataInfo<FileName> | PColumnValues,\n ) => (isDataInfo(data) ? data : makeJsonDataInfo(spec, data));\n\n return new AbstractPFrameDriver({\n logger,\n localBlobProvider,\n remoteBlobProvider,\n resolveDataInfo,\n });\n}\n"],"mappings":";;;;;;;;;;;;;;AAyBA,SAAgB,eAAe,YAAgC;AAC7D,KAAI,CAACA,gBAAG,SAAS,YAAY,EAAE,gBAAgB,OAAO,CAAC,EAAE,aAAa,EAAE;EACtE,MAAM,QAAQ,IAAIC,kDAAkB,sBAAsB;AAC1D,QAAM,wBAAQ,IAAI,MAAM,UAAU,WAAW,iBAAiB;AAC9D,QAAM;;AAER,QAAO;;AAGT,SAAS,WAAW,KAA4C;AAC9D,QAAO;;AAGT,IAAM,wBAAN,cACUC,4CAEV;CACE,YAAY,AAAiB,YAAwB;AACnD,SAAO;EADoB;;CAI7B,AAAU,mBAAmB,QAA+C;AAC1E,SAAO,WAAW,OAAO;;CAG3B,AAAU,kBAAkB,QAAkB,MAA6C;EACzF,MAAM,WAAWC,kBAAK,KAAK,KAAK,YAAY,OAAO;AACnD,MAAI,CAACH,gBAAG,SAAS,UAAU,EAAE,gBAAgB,OAAO,CAAC,EAAE,QAAQ,EAAE;GAC/D,MAAM,QAAQ,IAAIC,kDAAkB,oBAAoB;AACxD,SAAM,wBAAQ,IAAI,MAAM,QAAQ,SAAS,iBAAiB;AAC1D,SAAM;;AAER,SAAO;;CAGT,AAAO,SAAS,QAA+C;EAC7D,MAAM,WAAW,MAAM,YAAY,OAAO;AAC1C,MAAI,CAAC,UAAU;GACb,MAAM,QAAQ,IAAIA,kDAAkB,kBAAkB;AACtD,SAAM,wBAAQ,IAAI,MAAM,gBAAgB,OAAO,aAAa;AAC5D,SAAM;;AAER,SAAO;;CAGT,AAAO,eACL,QAC0D;AAC1D,SAAO;GACL,aAAa,OAAO,aAA4C;GAChE,oBAAoB,OAAO,WAAwC;IACjE,MAAM,WAAW,KAAK,SAAS,OAAO;AACtC,WAAO,MAAMD,gBAAG,SAAS,SAAS,UAAU,EAAE,QAAQ,CAAC;;GAE1D;;;AAIL,IAAM,yBAAN,MAAM,uBAA+D;CACnE,YACE,AAAiB,MACjB,AAAiB,QACjB;EAFiB;EACA;;CAGnB,aAAoB,KAClB,YACA,QACA,eACiC;EACjC,MAAM,OAAO,IAAI,sBAAsB,WAAW;EAElD,MAAM,kBAAkB,MAAMI,4CAAY,cAAc;GAAE,SAAS;GAAY;GAAQ,CAAC;EAQxF,MAAM,UAAUA,4CAAY,qBAAqB,EAAE,OAPT,EACxC,UAAU,UAAU,WAAW;GAC7B,MAAM,SAAS,SAAS,MAAM,GAAG,CAACC,qDAAe,iBAAiB,OAAO;AACzE,UAAO,gBAAgB,QAAQ,QAA0C,OAAO;KAEnF,EAEyD,CAAC;AAG3D,SAAO,IAAI,uBAAuB,MAFnB,MAAMD,4CAAY,iBAAiB;GAAE,GAAG;GAAe;GAAS,CAAC,CAEjC;;CAGjD,AAAO,QAAQ,QAA0D;AACvE,SAAO,KAAK,KAAK,QAAQ,OAAO;;CAGlC,AAAO,iBAAgD;AACrD,SAAO,KAAK,OAAO;;CAGrB,OAAO,OAAO,gBAA+B;AAC3C,QAAM,KAAK,OAAO,MAAM;AACxB,QAAM,KAAK,KAAK,OAAO,eAAe;;;AAS1C,eAAsB,yBAAyB,EAC7C,kCAAqB,EACrB,SAAS,QAAQ,OAIqB;CACtC,MAAM,oBAAoB,IAAI,sBAAsB,WAAW;CAC/D,MAAM,qBAAqB,MAAM,uBAAuB,KAAK,YAAY,QAAQ,EAAE,CAAC;CAEpF,MAAM,mBACJ,MACA,yDACe,KAAK,GAAG,OAAOE,2CAAiB,MAAM,KAAK;AAE5D,QAAO,IAAIC,yCAAqB;EAC9B;EACA;EACA;EACA;EACD,CAAC"}
@@ -84,6 +84,7 @@ var RemoteBlobProviderImpl = class RemoteBlobProviderImpl {
84
84
  }
85
85
  async [Symbol.asyncDispose]() {
86
86
  await this.server.stop();
87
+ await this.pool[Symbol.asyncDispose]();
87
88
  }
88
89
  };
89
90
  async function createPFrameDriverDouble({ dataFolder = tmpdir(), logger = console.log }) {
@@ -1 +1 @@
1
- {"version":3,"file":"driver_double.js","names":[],"sources":["../src/driver_double.ts"],"sourcesContent":["import {\n isDataInfo,\n PFrameDriverError,\n type Branded,\n type PColumnSpec,\n type PColumnValues,\n} from \"@milaboratories/pl-model-common\";\nimport { PFrameInternal } from \"@milaboratories/pl-model-middle-layer\";\nimport { RefCountPoolBase, type PoolEntry } from \"@milaboratories/ts-helpers\";\nimport { HttpHelpers } from \"@milaboratories/pframes-rs-node\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { tmpdir } from \"node:os\";\nimport type { AbstractInternalPFrameDriver } from \"./driver_decl\";\nimport {\n AbstractPFrameDriver,\n type LocalBlobProvider,\n type RemoteBlobProvider,\n} from \"./driver_impl\";\nimport { makeJsonDataInfo } from \"./data_info_helpers\";\n\nexport type FileName = Branded<string, \"FileName\">;\nexport type FilePath = Branded<string, \"FilePath\">;\nexport type FolderPath = Branded<string, \"FolderPath\">;\n\nexport function makeFolderPath(dataFolder: string): FolderPath {\n if (!fs.statSync(dataFolder, { throwIfNoEntry: false })?.isDirectory()) {\n const error = new PFrameDriverError(`Invalid data folder`);\n error.cause = new Error(`Folder ${dataFolder} does not exist`);\n throw error;\n }\n return dataFolder as FolderPath;\n}\n\nfunction makeBlobId(res: FileName): PFrameInternal.PFrameBlobId {\n return res as string as PFrameInternal.PFrameBlobId;\n}\n\nclass LocalBlobProviderImpl\n extends RefCountPoolBase<FileName, PFrameInternal.PFrameBlobId, FilePath>\n implements LocalBlobProvider<FileName>\n{\n constructor(private readonly dataFolder: FolderPath) {\n super();\n }\n\n protected calculateParamsKey(params: FileName): PFrameInternal.PFrameBlobId {\n return makeBlobId(params);\n }\n\n protected createNewResource(params: FileName, _key: PFrameInternal.PFrameBlobId): FilePath {\n const filePath = path.join(this.dataFolder, params);\n if (!fs.statSync(filePath, { throwIfNoEntry: false })?.isFile()) {\n const error = new PFrameDriverError(`Invalid file name`);\n error.cause = new Error(`File ${filePath} does not exist`);\n throw error;\n }\n return filePath as FilePath;\n }\n\n public getByKey(blobId: PFrameInternal.PFrameBlobId): FilePath {\n const resource = super.tryGetByKey(blobId);\n if (!resource) {\n const error = new PFrameDriverError(`Invalid blob id`);\n error.cause = new Error(`Blob with id ${blobId} not found.`);\n throw error;\n }\n return resource;\n }\n\n public makeDataSource(\n signal: AbortSignal,\n ): Omit<PFrameInternal.PFrameDataSourceV2, \"parquetServer\"> {\n return {\n preloadBlob: async (_blobIds: PFrameInternal.PFrameBlobId[]) => {},\n resolveBlobContent: async (blobId: PFrameInternal.PFrameBlobId) => {\n const filePath = this.getByKey(blobId);\n return await fs.promises.readFile(filePath, { signal });\n },\n };\n }\n}\n\nclass RemoteBlobProviderImpl implements RemoteBlobProvider<FileName> {\n constructor(\n private readonly pool: LocalBlobProviderImpl,\n private readonly server: PFrameInternal.HttpServer,\n ) {}\n\n public static async init(\n dataFolder: FolderPath,\n logger: PFrameInternal.Logger,\n serverOptions: Omit<PFrameInternal.HttpServerOptions, \"handler\">,\n ): Promise<RemoteBlobProviderImpl> {\n const pool = new LocalBlobProviderImpl(dataFolder);\n\n const underlyingStore = await HttpHelpers.createFsStore({ rootDir: dataFolder, logger });\n const store: PFrameInternal.ObjectStore = {\n request: (filename, params) => {\n const blobId = filename.slice(0, -PFrameInternal.ParquetExtension.length);\n return underlyingStore.request(blobId as PFrameInternal.ParquetFileName, params);\n },\n };\n\n const handler = HttpHelpers.createRequestHandler({ store });\n const server = await HttpHelpers.createHttpServer({ ...serverOptions, handler });\n\n return new RemoteBlobProviderImpl(pool, server);\n }\n\n public acquire(params: FileName): PoolEntry<PFrameInternal.PFrameBlobId> {\n return this.pool.acquire(params);\n }\n\n public httpServerInfo(): PFrameInternal.HttpServerInfo {\n return this.server.info;\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n await this.server.stop();\n }\n}\n\nexport type InternalPFrameDriverDouble = AbstractInternalPFrameDriver<\n PFrameInternal.DataInfo<FileName> | PColumnValues\n>;\n\n// It's mock for testing purposes, not a real test!\nexport async function createPFrameDriverDouble({\n dataFolder = tmpdir() as FolderPath,\n logger = console.log,\n}: {\n dataFolder?: FolderPath;\n logger?: PFrameInternal.Logger;\n}): Promise<InternalPFrameDriverDouble> {\n const localBlobProvider = new LocalBlobProviderImpl(dataFolder);\n const remoteBlobProvider = await RemoteBlobProviderImpl.init(dataFolder, logger, {});\n\n const resolveDataInfo = (\n spec: PColumnSpec,\n data: PFrameInternal.DataInfo<FileName> | PColumnValues,\n ) => (isDataInfo(data) ? data : makeJsonDataInfo(spec, data));\n\n return new AbstractPFrameDriver({\n logger,\n localBlobProvider,\n remoteBlobProvider,\n resolveDataInfo,\n });\n}\n"],"mappings":";;;;;;;;;;;AAyBA,SAAgB,eAAe,YAAgC;AAC7D,KAAI,CAAC,GAAG,SAAS,YAAY,EAAE,gBAAgB,OAAO,CAAC,EAAE,aAAa,EAAE;EACtE,MAAM,QAAQ,IAAI,kBAAkB,sBAAsB;AAC1D,QAAM,wBAAQ,IAAI,MAAM,UAAU,WAAW,iBAAiB;AAC9D,QAAM;;AAER,QAAO;;AAGT,SAAS,WAAW,KAA4C;AAC9D,QAAO;;AAGT,IAAM,wBAAN,cACU,iBAEV;CACE,YAAY,AAAiB,YAAwB;AACnD,SAAO;EADoB;;CAI7B,AAAU,mBAAmB,QAA+C;AAC1E,SAAO,WAAW,OAAO;;CAG3B,AAAU,kBAAkB,QAAkB,MAA6C;EACzF,MAAM,WAAW,KAAK,KAAK,KAAK,YAAY,OAAO;AACnD,MAAI,CAAC,GAAG,SAAS,UAAU,EAAE,gBAAgB,OAAO,CAAC,EAAE,QAAQ,EAAE;GAC/D,MAAM,QAAQ,IAAI,kBAAkB,oBAAoB;AACxD,SAAM,wBAAQ,IAAI,MAAM,QAAQ,SAAS,iBAAiB;AAC1D,SAAM;;AAER,SAAO;;CAGT,AAAO,SAAS,QAA+C;EAC7D,MAAM,WAAW,MAAM,YAAY,OAAO;AAC1C,MAAI,CAAC,UAAU;GACb,MAAM,QAAQ,IAAI,kBAAkB,kBAAkB;AACtD,SAAM,wBAAQ,IAAI,MAAM,gBAAgB,OAAO,aAAa;AAC5D,SAAM;;AAER,SAAO;;CAGT,AAAO,eACL,QAC0D;AAC1D,SAAO;GACL,aAAa,OAAO,aAA4C;GAChE,oBAAoB,OAAO,WAAwC;IACjE,MAAM,WAAW,KAAK,SAAS,OAAO;AACtC,WAAO,MAAM,GAAG,SAAS,SAAS,UAAU,EAAE,QAAQ,CAAC;;GAE1D;;;AAIL,IAAM,yBAAN,MAAM,uBAA+D;CACnE,YACE,AAAiB,MACjB,AAAiB,QACjB;EAFiB;EACA;;CAGnB,aAAoB,KAClB,YACA,QACA,eACiC;EACjC,MAAM,OAAO,IAAI,sBAAsB,WAAW;EAElD,MAAM,kBAAkB,MAAM,YAAY,cAAc;GAAE,SAAS;GAAY;GAAQ,CAAC;EAQxF,MAAM,UAAU,YAAY,qBAAqB,EAAE,OAPT,EACxC,UAAU,UAAU,WAAW;GAC7B,MAAM,SAAS,SAAS,MAAM,GAAG,CAAC,eAAe,iBAAiB,OAAO;AACzE,UAAO,gBAAgB,QAAQ,QAA0C,OAAO;KAEnF,EAEyD,CAAC;AAG3D,SAAO,IAAI,uBAAuB,MAFnB,MAAM,YAAY,iBAAiB;GAAE,GAAG;GAAe;GAAS,CAAC,CAEjC;;CAGjD,AAAO,QAAQ,QAA0D;AACvE,SAAO,KAAK,KAAK,QAAQ,OAAO;;CAGlC,AAAO,iBAAgD;AACrD,SAAO,KAAK,OAAO;;CAGrB,OAAO,OAAO,gBAA+B;AAC3C,QAAM,KAAK,OAAO,MAAM;;;AAS5B,eAAsB,yBAAyB,EAC7C,aAAa,QAAQ,EACrB,SAAS,QAAQ,OAIqB;CACtC,MAAM,oBAAoB,IAAI,sBAAsB,WAAW;CAC/D,MAAM,qBAAqB,MAAM,uBAAuB,KAAK,YAAY,QAAQ,EAAE,CAAC;CAEpF,MAAM,mBACJ,MACA,SACI,WAAW,KAAK,GAAG,OAAO,iBAAiB,MAAM,KAAK;AAE5D,QAAO,IAAI,qBAAqB;EAC9B;EACA;EACA;EACA;EACD,CAAC"}
1
+ {"version":3,"file":"driver_double.js","names":[],"sources":["../src/driver_double.ts"],"sourcesContent":["import {\n isDataInfo,\n PFrameDriverError,\n type Branded,\n type PColumnSpec,\n type PColumnValues,\n} from \"@milaboratories/pl-model-common\";\nimport { PFrameInternal } from \"@milaboratories/pl-model-middle-layer\";\nimport { RefCountPoolBase, type PoolEntry } from \"@milaboratories/ts-helpers\";\nimport { HttpHelpers } from \"@milaboratories/pframes-rs-node\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { tmpdir } from \"node:os\";\nimport type { AbstractInternalPFrameDriver } from \"./driver_decl\";\nimport {\n AbstractPFrameDriver,\n type LocalBlobProvider,\n type RemoteBlobProvider,\n} from \"./driver_impl\";\nimport { makeJsonDataInfo } from \"./data_info_helpers\";\n\nexport type FileName = Branded<string, \"FileName\">;\nexport type FilePath = Branded<string, \"FilePath\">;\nexport type FolderPath = Branded<string, \"FolderPath\">;\n\nexport function makeFolderPath(dataFolder: string): FolderPath {\n if (!fs.statSync(dataFolder, { throwIfNoEntry: false })?.isDirectory()) {\n const error = new PFrameDriverError(`Invalid data folder`);\n error.cause = new Error(`Folder ${dataFolder} does not exist`);\n throw error;\n }\n return dataFolder as FolderPath;\n}\n\nfunction makeBlobId(res: FileName): PFrameInternal.PFrameBlobId {\n return res as string as PFrameInternal.PFrameBlobId;\n}\n\nclass LocalBlobProviderImpl\n extends RefCountPoolBase<FileName, PFrameInternal.PFrameBlobId, FilePath>\n implements LocalBlobProvider<FileName>\n{\n constructor(private readonly dataFolder: FolderPath) {\n super();\n }\n\n protected calculateParamsKey(params: FileName): PFrameInternal.PFrameBlobId {\n return makeBlobId(params);\n }\n\n protected createNewResource(params: FileName, _key: PFrameInternal.PFrameBlobId): FilePath {\n const filePath = path.join(this.dataFolder, params);\n if (!fs.statSync(filePath, { throwIfNoEntry: false })?.isFile()) {\n const error = new PFrameDriverError(`Invalid file name`);\n error.cause = new Error(`File ${filePath} does not exist`);\n throw error;\n }\n return filePath as FilePath;\n }\n\n public getByKey(blobId: PFrameInternal.PFrameBlobId): FilePath {\n const resource = super.tryGetByKey(blobId);\n if (!resource) {\n const error = new PFrameDriverError(`Invalid blob id`);\n error.cause = new Error(`Blob with id ${blobId} not found.`);\n throw error;\n }\n return resource;\n }\n\n public makeDataSource(\n signal: AbortSignal,\n ): Omit<PFrameInternal.PFrameDataSourceV2, \"parquetServer\"> {\n return {\n preloadBlob: async (_blobIds: PFrameInternal.PFrameBlobId[]) => {},\n resolveBlobContent: async (blobId: PFrameInternal.PFrameBlobId) => {\n const filePath = this.getByKey(blobId);\n return await fs.promises.readFile(filePath, { signal });\n },\n };\n }\n}\n\nclass RemoteBlobProviderImpl implements RemoteBlobProvider<FileName> {\n constructor(\n private readonly pool: LocalBlobProviderImpl,\n private readonly server: PFrameInternal.HttpServer,\n ) {}\n\n public static async init(\n dataFolder: FolderPath,\n logger: PFrameInternal.Logger,\n serverOptions: Omit<PFrameInternal.HttpServerOptions, \"handler\">,\n ): Promise<RemoteBlobProviderImpl> {\n const pool = new LocalBlobProviderImpl(dataFolder);\n\n const underlyingStore = await HttpHelpers.createFsStore({ rootDir: dataFolder, logger });\n const store: PFrameInternal.ObjectStore = {\n request: (filename, params) => {\n const blobId = filename.slice(0, -PFrameInternal.ParquetExtension.length);\n return underlyingStore.request(blobId as PFrameInternal.ParquetFileName, params);\n },\n };\n\n const handler = HttpHelpers.createRequestHandler({ store });\n const server = await HttpHelpers.createHttpServer({ ...serverOptions, handler });\n\n return new RemoteBlobProviderImpl(pool, server);\n }\n\n public acquire(params: FileName): PoolEntry<PFrameInternal.PFrameBlobId> {\n return this.pool.acquire(params);\n }\n\n public httpServerInfo(): PFrameInternal.HttpServerInfo {\n return this.server.info;\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n await this.server.stop();\n await this.pool[Symbol.asyncDispose]();\n }\n}\n\nexport type InternalPFrameDriverDouble = AbstractInternalPFrameDriver<\n PFrameInternal.DataInfo<FileName> | PColumnValues\n>;\n\n// It's mock for testing purposes, not a real test!\nexport async function createPFrameDriverDouble({\n dataFolder = tmpdir() as FolderPath,\n logger = console.log,\n}: {\n dataFolder?: FolderPath;\n logger?: PFrameInternal.Logger;\n}): Promise<InternalPFrameDriverDouble> {\n const localBlobProvider = new LocalBlobProviderImpl(dataFolder);\n const remoteBlobProvider = await RemoteBlobProviderImpl.init(dataFolder, logger, {});\n\n const resolveDataInfo = (\n spec: PColumnSpec,\n data: PFrameInternal.DataInfo<FileName> | PColumnValues,\n ) => (isDataInfo(data) ? data : makeJsonDataInfo(spec, data));\n\n return new AbstractPFrameDriver({\n logger,\n localBlobProvider,\n remoteBlobProvider,\n resolveDataInfo,\n });\n}\n"],"mappings":";;;;;;;;;;;AAyBA,SAAgB,eAAe,YAAgC;AAC7D,KAAI,CAAC,GAAG,SAAS,YAAY,EAAE,gBAAgB,OAAO,CAAC,EAAE,aAAa,EAAE;EACtE,MAAM,QAAQ,IAAI,kBAAkB,sBAAsB;AAC1D,QAAM,wBAAQ,IAAI,MAAM,UAAU,WAAW,iBAAiB;AAC9D,QAAM;;AAER,QAAO;;AAGT,SAAS,WAAW,KAA4C;AAC9D,QAAO;;AAGT,IAAM,wBAAN,cACU,iBAEV;CACE,YAAY,AAAiB,YAAwB;AACnD,SAAO;EADoB;;CAI7B,AAAU,mBAAmB,QAA+C;AAC1E,SAAO,WAAW,OAAO;;CAG3B,AAAU,kBAAkB,QAAkB,MAA6C;EACzF,MAAM,WAAW,KAAK,KAAK,KAAK,YAAY,OAAO;AACnD,MAAI,CAAC,GAAG,SAAS,UAAU,EAAE,gBAAgB,OAAO,CAAC,EAAE,QAAQ,EAAE;GAC/D,MAAM,QAAQ,IAAI,kBAAkB,oBAAoB;AACxD,SAAM,wBAAQ,IAAI,MAAM,QAAQ,SAAS,iBAAiB;AAC1D,SAAM;;AAER,SAAO;;CAGT,AAAO,SAAS,QAA+C;EAC7D,MAAM,WAAW,MAAM,YAAY,OAAO;AAC1C,MAAI,CAAC,UAAU;GACb,MAAM,QAAQ,IAAI,kBAAkB,kBAAkB;AACtD,SAAM,wBAAQ,IAAI,MAAM,gBAAgB,OAAO,aAAa;AAC5D,SAAM;;AAER,SAAO;;CAGT,AAAO,eACL,QAC0D;AAC1D,SAAO;GACL,aAAa,OAAO,aAA4C;GAChE,oBAAoB,OAAO,WAAwC;IACjE,MAAM,WAAW,KAAK,SAAS,OAAO;AACtC,WAAO,MAAM,GAAG,SAAS,SAAS,UAAU,EAAE,QAAQ,CAAC;;GAE1D;;;AAIL,IAAM,yBAAN,MAAM,uBAA+D;CACnE,YACE,AAAiB,MACjB,AAAiB,QACjB;EAFiB;EACA;;CAGnB,aAAoB,KAClB,YACA,QACA,eACiC;EACjC,MAAM,OAAO,IAAI,sBAAsB,WAAW;EAElD,MAAM,kBAAkB,MAAM,YAAY,cAAc;GAAE,SAAS;GAAY;GAAQ,CAAC;EAQxF,MAAM,UAAU,YAAY,qBAAqB,EAAE,OAPT,EACxC,UAAU,UAAU,WAAW;GAC7B,MAAM,SAAS,SAAS,MAAM,GAAG,CAAC,eAAe,iBAAiB,OAAO;AACzE,UAAO,gBAAgB,QAAQ,QAA0C,OAAO;KAEnF,EAEyD,CAAC;AAG3D,SAAO,IAAI,uBAAuB,MAFnB,MAAM,YAAY,iBAAiB;GAAE,GAAG;GAAe;GAAS,CAAC,CAEjC;;CAGjD,AAAO,QAAQ,QAA0D;AACvE,SAAO,KAAK,KAAK,QAAQ,OAAO;;CAGlC,AAAO,iBAAgD;AACrD,SAAO,KAAK,OAAO;;CAGrB,OAAO,OAAO,gBAA+B;AAC3C,QAAM,KAAK,OAAO,MAAM;AACxB,QAAM,KAAK,KAAK,OAAO,eAAe;;;AAS1C,eAAsB,yBAAyB,EAC7C,aAAa,QAAQ,EACrB,SAAS,QAAQ,OAIqB;CACtC,MAAM,oBAAoB,IAAI,sBAAsB,WAAW;CAC/D,MAAM,qBAAqB,MAAM,uBAAuB,KAAK,YAAY,QAAQ,EAAE,CAAC;CAEpF,MAAM,mBACJ,MACA,SACI,WAAW,KAAK,GAAG,OAAO,iBAAiB,MAAM,KAAK;AAE5D,QAAO,IAAI,qBAAqB;EAC9B;EACA;EACA;EACA;EACD,CAAC"}
@@ -48,62 +48,88 @@ var AbstractPFrameDriver = class {
48
48
  this.pTableCachePlain = new require_ptable_cache_plain.PTableCachePlain(this.logger, options);
49
49
  }
50
50
  async dispose() {
51
- return await this.remoteBlobProvider[Symbol.asyncDispose]();
51
+ await Promise.allSettled([
52
+ this.pTables[Symbol.asyncDispose](),
53
+ this.pTableDefs[Symbol.asyncDispose](),
54
+ this.pFrames[Symbol.asyncDispose](),
55
+ this.localBlobProvider[Symbol.asyncDispose](),
56
+ this.remoteBlobProvider[Symbol.asyncDispose]()
57
+ ]);
52
58
  }
53
59
  async [Symbol.asyncDispose]() {
54
60
  return await this.dispose();
55
61
  }
56
62
  createPFrame(def) {
57
63
  const ValueTypes = new Set(Object.values(_milaboratories_pl_model_common.ValueType));
58
- const columns = (0, _milaboratories_pl_model_common.uniqueBy)(def.filter((column) => ValueTypes.has(column.spec.valueType)), (column) => column.id).map((c) => (0, _milaboratories_pl_model_common.mapPObjectData)(c, (d) => this.resolveDataInfo(c.spec, d)));
64
+ const columns = (0, _milaboratories_pl_model_common.uniqueBy)(def.filter((column) => ValueTypes.has(column.spec.valueType)).map((c) => ({
65
+ ...c,
66
+ spec: (0, _milaboratories_pl_model_common.resolveAnnotationParents)(c.spec)
67
+ })), (column) => column.id).map((c) => (0, _milaboratories_pl_model_common.mapPObjectData)(c, (d) => this.resolveDataInfo(c.spec, d)));
59
68
  return this.pFrames.acquire(columns);
60
69
  }
61
70
  createPTable(rawDef) {
62
- const pFrameEntry = this.createPFrame((0, _milaboratories_pl_model_common.extractAllColumns)(rawDef.src));
63
- const sortedDef = (0, _milaboratories_pl_model_common.sortPTableDef)(migrateTableFilter((0, _milaboratories_pl_model_common.mapPTableDef)(rawDef, (c) => c.id), this.logger));
64
- const pTableEntry = this.pTableDefs.acquire({
65
- type: "v1",
66
- def: sortedDef,
67
- pFrameHandle: pFrameEntry.key
68
- });
69
- if (require_logging.logPFrames()) this.logger("info", `Create PTable call (pFrameHandle = ${pFrameEntry.key}; pTableHandle = ${pTableEntry.key})`);
70
- const unref = () => {
71
- pTableEntry.unref();
72
- pFrameEntry.unref();
73
- };
74
- return {
75
- key: pTableEntry.key,
76
- resource: pTableEntry.resource,
77
- unref,
78
- [Symbol.dispose]: unref
79
- };
71
+ try {
72
+ var _usingCtx$1 = require_usingCtx._usingCtx();
73
+ const pFrameGuard = _usingCtx$1.u(new _milaboratories_ts_helpers.PoolEntryGuard(this.createPFrame((0, _milaboratories_pl_model_common.extractAllColumns)(rawDef.src))));
74
+ const sortedDef = (0, _milaboratories_pl_model_common.sortPTableDef)(migrateTableFilter((0, _milaboratories_pl_model_common.mapPTableDef)(rawDef, (c) => c.id), this.logger));
75
+ const pTableEntry = this.pTableDefs.acquire({
76
+ type: "v1",
77
+ def: sortedDef,
78
+ pFrameHandle: pFrameGuard.key
79
+ });
80
+ if (require_logging.logPFrames()) this.logger("info", `Create PTable call (pFrameHandle = ${pFrameGuard.key}; pTableHandle = ${pTableEntry.key})`);
81
+ const pFrameEntry = pFrameGuard.keep();
82
+ const unref = () => {
83
+ pTableEntry.unref();
84
+ pFrameEntry.unref();
85
+ };
86
+ return {
87
+ key: pTableEntry.key,
88
+ resource: pTableEntry.resource,
89
+ unref,
90
+ [Symbol.dispose]: unref
91
+ };
92
+ } catch (_) {
93
+ _usingCtx$1.e = _;
94
+ } finally {
95
+ _usingCtx$1.d();
96
+ }
80
97
  }
81
98
  createPTableV2(def) {
82
- const columns = (0, _milaboratories_pl_model_common.uniqueBy)((0, _milaboratories_pl_model_common.collectSpecQueryColumns)(def.query), (c) => c.id);
83
- const columnsMap = columns.reduce((acc, col) => (acc[col.id] = col.spec, acc), {});
84
- const pFrameEntry = this.createPFrame(columns);
85
- const specFrame = (0, _milaboratories_pframes_rs_wasm.createPFrame)(columnsMap);
86
- const sortedQuery = (0, _milaboratories_pl_model_common.sortSpecQuery)((0, _milaboratories_pl_model_common.mapSpecQueryColumns)(def.query, (c) => c.id));
87
- const { tableSpec, dataQuery } = specFrame.evaluateQuery(sortedQuery);
88
- const pTableEntry = this.pTableDefs.acquire({
89
- type: "v2",
90
- pFrameHandle: pFrameEntry.key,
91
- def: {
92
- tableSpec,
93
- dataQuery
94
- }
95
- });
96
- if (require_logging.logPFrames()) this.logger("info", `Create PTable call (pFrameHandle = ${pFrameEntry.key}; pTableHandle = ${pTableEntry.key})`);
97
- const unref = () => {
98
- pTableEntry.unref();
99
- pFrameEntry.unref();
100
- };
101
- return {
102
- key: pTableEntry.key,
103
- resource: pTableEntry.resource,
104
- unref,
105
- [Symbol.dispose]: unref
106
- };
99
+ try {
100
+ var _usingCtx3 = require_usingCtx._usingCtx();
101
+ const columns = (0, _milaboratories_pl_model_common.uniqueBy)((0, _milaboratories_pl_model_common.collectSpecQueryColumns)(def.query), (c) => c.id);
102
+ const columnsMap = columns.reduce((acc, col) => (acc[col.id] = col.spec, acc), {});
103
+ const pFrameGuard = _usingCtx3.u(new _milaboratories_ts_helpers.PoolEntryGuard(this.createPFrame(columns)));
104
+ const ValueTypes = new Set(Object.values(_milaboratories_pl_model_common.ValueType));
105
+ const specFrame = (0, _milaboratories_pframes_rs_wasm.createPFrame)(Object.fromEntries(Object.entries(columnsMap).filter(([, spec]) => ValueTypes.has(spec.valueType)).map(([id, spec]) => [id, (0, _milaboratories_pl_model_common.resolveAnnotationParents)(spec)])));
106
+ const sortedQuery = (0, _milaboratories_pl_model_common.sortSpecQuery)((0, _milaboratories_pl_model_common.mapSpecQueryColumns)(def.query, (c) => c.id));
107
+ const { tableSpec, dataQuery } = specFrame.evaluateQuery(sortedQuery);
108
+ const pTableEntry = this.pTableDefs.acquire({
109
+ type: "v2",
110
+ pFrameHandle: pFrameGuard.key,
111
+ def: {
112
+ tableSpec,
113
+ dataQuery
114
+ }
115
+ });
116
+ if (require_logging.logPFrames()) this.logger("info", `Create PTable call (pFrameHandle = ${pFrameGuard.key}; pTableHandle = ${pTableEntry.key})`);
117
+ const pFrameEntry = pFrameGuard.keep();
118
+ const unref = () => {
119
+ pTableEntry.unref();
120
+ pFrameEntry.unref();
121
+ };
122
+ return {
123
+ key: pTableEntry.key,
124
+ resource: pTableEntry.resource,
125
+ unref,
126
+ [Symbol.dispose]: unref
127
+ };
128
+ } catch (_) {
129
+ _usingCtx3.e = _;
130
+ } finally {
131
+ _usingCtx3.d();
132
+ }
107
133
  }
108
134
  async findColumns(handle, request) {
109
135
  const iRequest = {
@@ -125,33 +151,35 @@ var AbstractPFrameDriver = class {
125
151
  return await (await pFramePromise).listColumns();
126
152
  }
127
153
  async calculateTableData(handle, request, range, signal) {
128
- if (require_logging.logPFrames()) this.logger("info", `Call calculateTableData, handle = ${handle}, request = ${JSON.stringify(request, _milaboratories_pl_model_common.bigintReplacer)}`);
129
- const table = this.pTables.acquire({
130
- type: "v1",
131
- pFrameHandle: handle,
132
- def: (0, _milaboratories_pl_model_common.sortPTableDef)(migrateTableFilter(request, this.logger))
133
- });
134
- const { pTablePromise, disposeSignal } = table.resource;
135
- const pTable = await pTablePromise;
136
- const combinedSignal = AbortSignal.any([signal, disposeSignal].filter((s) => !!s));
137
- return await this.frameConcurrencyLimiter.run(async () => {
138
- try {
154
+ try {
155
+ var _usingCtx4 = require_usingCtx._usingCtx();
156
+ if (require_logging.logPFrames()) this.logger("info", `Call calculateTableData, handle = ${handle}, request = ${JSON.stringify(request, _milaboratories_pl_model_common.bigintReplacer)}`);
157
+ const tableGuard = _usingCtx4.u(new _milaboratories_ts_helpers.PoolEntryGuard(this.pTables.acquire({
158
+ type: "v1",
159
+ pFrameHandle: handle,
160
+ def: (0, _milaboratories_pl_model_common.sortPTableDef)(migrateTableFilter(request, this.logger))
161
+ })));
162
+ const { pTablePromise, disposeSignal } = tableGuard.resource;
163
+ const pTable = await pTablePromise;
164
+ const combinedSignal = AbortSignal.any([signal, disposeSignal].filter((s) => !!s));
165
+ return await this.frameConcurrencyLimiter.run(async () => {
139
166
  const spec = pTable.getSpec();
140
167
  const data = await pTable.getData([...spec.keys()], {
141
168
  range,
142
169
  signal: combinedSignal
143
170
  });
144
171
  const overallSize = await pTable.getFootprint({ signal: combinedSignal });
145
- this.pTableCachePerFrame.cache(table, overallSize);
172
+ this.pTableCachePerFrame.cache(tableGuard.keep(), overallSize);
146
173
  return spec.map((spec, i) => ({
147
174
  spec,
148
175
  data: data[i]
149
176
  }));
150
- } catch (err) {
151
- table.unref();
152
- throw err;
153
- }
154
- });
177
+ });
178
+ } catch (_) {
179
+ _usingCtx4.e = _;
180
+ } finally {
181
+ _usingCtx4.d();
182
+ }
155
183
  }
156
184
  async getUniqueValues(handle, request, signal) {
157
185
  if (require_logging.logPFrames()) this.logger("info", `Call getUniqueValues, handle = ${handle}, request = ${JSON.stringify(request, _milaboratories_pl_model_common.bigintReplacer)}`);
@@ -167,48 +195,62 @@ var AbstractPFrameDriver = class {
167
195
  }
168
196
  async getSpec(handle) {
169
197
  try {
170
- var _usingCtx$1 = require_usingCtx._usingCtx();
198
+ var _usingCtx5 = require_usingCtx._usingCtx();
171
199
  const { def } = this.pTableDefs.getByKey(handle);
172
- const { pTablePromise } = _usingCtx$1.u(this.pTables.acquire(def)).resource;
200
+ const { pTablePromise } = _usingCtx5.u(this.pTables.acquire(def)).resource;
173
201
  return (await pTablePromise).getSpec();
174
202
  } catch (_) {
175
- _usingCtx$1.e = _;
203
+ _usingCtx5.e = _;
176
204
  } finally {
177
- _usingCtx$1.d();
205
+ _usingCtx5.d();
178
206
  }
179
207
  }
180
208
  async getShape(handle, signal) {
181
- const { def, disposeSignal: defDisposeSignal } = this.pTableDefs.getByKey(handle);
182
- const table = this.pTables.acquire(def);
183
- const { pTablePromise, disposeSignal } = table.resource;
184
- const pTable = await pTablePromise;
185
- const combinedSignal = AbortSignal.any([signal, disposeSignal].filter((s) => !!s));
186
- const { shape, overallSize } = await this.tableConcurrencyLimiter.run(async () => {
187
- return {
188
- shape: await pTable.getShape({ signal: combinedSignal }),
189
- overallSize: await pTable.getFootprint({ signal: combinedSignal })
190
- };
191
- });
192
- this.pTableCachePlain.cache(table, overallSize, defDisposeSignal);
193
- return shape;
209
+ try {
210
+ var _usingCtx6 = require_usingCtx._usingCtx();
211
+ const { def, disposeSignal: defDisposeSignal } = this.pTableDefs.getByKey(handle);
212
+ const tableGuard = _usingCtx6.u(new _milaboratories_ts_helpers.PoolEntryGuard(this.pTables.acquire(def)));
213
+ const { pTablePromise, disposeSignal } = tableGuard.resource;
214
+ const pTable = await pTablePromise;
215
+ const combinedSignal = AbortSignal.any([signal, disposeSignal].filter((s) => !!s));
216
+ const { shape, overallSize } = await this.tableConcurrencyLimiter.run(async () => {
217
+ return {
218
+ shape: await pTable.getShape({ signal: combinedSignal }),
219
+ overallSize: await pTable.getFootprint({ signal: combinedSignal })
220
+ };
221
+ });
222
+ this.pTableCachePlain.cache(tableGuard.keep(), overallSize, defDisposeSignal);
223
+ return shape;
224
+ } catch (_) {
225
+ _usingCtx6.e = _;
226
+ } finally {
227
+ _usingCtx6.d();
228
+ }
194
229
  }
195
230
  async getData(handle, columnIndices, range, signal) {
196
- const { def, disposeSignal: defDisposeSignal } = this.pTableDefs.getByKey(handle);
197
- const table = this.pTables.acquire(def);
198
- const { pTablePromise, disposeSignal } = table.resource;
199
- const pTable = await pTablePromise;
200
- const combinedSignal = AbortSignal.any([signal, disposeSignal].filter((s) => !!s));
201
- const { data, overallSize } = await this.tableConcurrencyLimiter.run(async () => {
202
- return {
203
- data: await pTable.getData(columnIndices, {
204
- range,
205
- signal: combinedSignal
206
- }),
207
- overallSize: await pTable.getFootprint({ signal: combinedSignal })
208
- };
209
- });
210
- this.pTableCachePlain.cache(table, overallSize, defDisposeSignal);
211
- return data;
231
+ try {
232
+ var _usingCtx7 = require_usingCtx._usingCtx();
233
+ const { def, disposeSignal: defDisposeSignal } = this.pTableDefs.getByKey(handle);
234
+ const tableGuard = _usingCtx7.u(new _milaboratories_ts_helpers.PoolEntryGuard(this.pTables.acquire(def)));
235
+ const { pTablePromise, disposeSignal } = tableGuard.resource;
236
+ const pTable = await pTablePromise;
237
+ const combinedSignal = AbortSignal.any([signal, disposeSignal].filter((s) => !!s));
238
+ const { data, overallSize } = await this.tableConcurrencyLimiter.run(async () => {
239
+ return {
240
+ data: await pTable.getData(columnIndices, {
241
+ range,
242
+ signal: combinedSignal
243
+ }),
244
+ overallSize: await pTable.getFootprint({ signal: combinedSignal })
245
+ };
246
+ });
247
+ this.pTableCachePlain.cache(tableGuard.keep(), overallSize, defDisposeSignal);
248
+ return data;
249
+ } catch (_) {
250
+ _usingCtx7.e = _;
251
+ } finally {
252
+ _usingCtx7.d();
253
+ }
212
254
  }
213
255
  };
214
256
  function migrateFilters(filters, logger) {
@@ -1 +1 @@
1
- {"version":3,"file":"driver_impl.cjs","names":["PTableCachePerFrameOpsDefaults","PTableCachePlainOpsDefaults","PFrameFactory","ConcurrencyLimitingExecutor","PFramePool","PTableDefPool","PTablePool","PTableCachePerFrame","PTableCachePlain","ValueType","logPFrames","bigintReplacer"],"sources":["../src/driver_impl.ts"],"sourcesContent":["import {\n mapPObjectData,\n mapPTableDef,\n extractAllColumns,\n uniqueBy,\n canonicalizeJson,\n bigintReplacer,\n ValueType,\n type CalculateTableDataRequest,\n type CalculateTableDataResponse,\n type FindColumnsRequest,\n type FindColumnsResponse,\n type PColumnIdAndSpec,\n type PColumnSpec,\n type PFrameHandle,\n type PObjectId,\n type PTableColumnSpec,\n type PTableHandle,\n type PTableShape,\n type PTableVector,\n type TableRange,\n type UniqueValuesRequest,\n type UniqueValuesResponse,\n type PColumn,\n type PFrameDef,\n type PTableDef,\n type PTableRecordSingleValueFilterV2,\n type PTableRecordFilter,\n type JsonSerializable,\n type PTableDefV2,\n mapSpecQueryColumns,\n collectSpecQueryColumns,\n sortSpecQuery,\n sortPTableDef,\n} from \"@milaboratories/pl-model-common\";\nimport type { PFrameInternal } from \"@milaboratories/pl-model-middle-layer\";\nimport { ConcurrencyLimitingExecutor, type PoolEntry } from \"@milaboratories/ts-helpers\";\nimport { PFrameFactory } from \"@milaboratories/pframes-rs-node\";\nimport { tmpdir } from \"node:os\";\nimport type { AbstractInternalPFrameDriver } from \"./driver_decl\";\nimport { logPFrames } from \"./logging\";\nimport {\n PFramePool,\n type LocalBlobProvider as PoolLocalBlobProvider,\n type RemoteBlobProvider as PoolRemoteBlobProvider,\n} from \"./pframe_pool\";\nimport { PTableDefPool } from \"./ptable_def_pool\";\nimport { PTablePool } from \"./ptable_pool\";\nimport {\n PTableCachePerFrame,\n PTableCachePerFrameOpsDefaults,\n type PTableCachePerFrameOps,\n} from \"./ptable_cache_per_frame\";\nimport {\n PTableCachePlain,\n PTableCachePlainOpsDefaults,\n type PTableCachePlainOps,\n} from \"./ptable_cache_plain\";\nimport { createPFrame as createSpecFrame } from \"@milaboratories/pframes-rs-wasm\";\n\nexport interface LocalBlobProvider<\n TreeEntry extends JsonSerializable,\n> extends PoolLocalBlobProvider<TreeEntry> {}\n\nexport interface RemoteBlobProvider<TreeEntry extends JsonSerializable>\n extends PoolRemoteBlobProvider<TreeEntry>, AsyncDisposable {}\n\nexport type AbstractPFrameDriverOps = PTableCachePerFrameOps &\n PTableCachePlainOps & {\n /** Concurrency limits for `getUniqueValues` and `calculateTableData` requests */\n pFrameConcurrency: number;\n /** Concurrency limits for `getShape` and `getData` requests */\n pTableConcurrency: number;\n };\n\nexport const AbstractPFrameDriverOpsDefaults: AbstractPFrameDriverOps = {\n ...PTableCachePerFrameOpsDefaults,\n ...PTableCachePlainOpsDefaults,\n pFrameConcurrency: 1, // 1 join is executed in parallel and utilize all RAM and CPU cores\n pTableConcurrency: 1, // 1 joined table is read from disk at a time, which matches 1 table the user can view in the UI\n};\n\nexport type DataInfoResolver<PColumnData, TreeEntry extends JsonSerializable> = (\n spec: PColumnSpec,\n data: PColumnData,\n) => PFrameInternal.DataInfo<TreeEntry>;\n\nexport class AbstractPFrameDriver<\n PColumnData,\n TreeEntry extends JsonSerializable,\n> implements AbstractInternalPFrameDriver<PColumnData> {\n private readonly logger: PFrameInternal.Logger;\n\n private readonly localBlobProvider: LocalBlobProvider<TreeEntry>;\n private readonly remoteBlobProvider: RemoteBlobProvider<TreeEntry>;\n\n private readonly resolveDataInfo: DataInfoResolver<PColumnData, TreeEntry>;\n\n private readonly pFrames: PFramePool<TreeEntry>;\n private readonly pTableDefs: PTableDefPool;\n private readonly pTables: PTablePool<TreeEntry>;\n\n private readonly pTableCachePerFrame: PTableCachePerFrame;\n private readonly pTableCachePlain: PTableCachePlain;\n\n private readonly frameConcurrencyLimiter: ConcurrencyLimitingExecutor;\n private readonly tableConcurrencyLimiter: ConcurrencyLimitingExecutor;\n\n public async pprofDump(): Promise<Uint8Array> {\n return await PFrameFactory.pprofDump();\n }\n\n public constructor({\n logger = () => {},\n localBlobProvider,\n remoteBlobProvider,\n spillPath = tmpdir(),\n options = AbstractPFrameDriverOpsDefaults,\n resolveDataInfo,\n }: {\n logger?: PFrameInternal.Logger;\n localBlobProvider: LocalBlobProvider<TreeEntry>;\n remoteBlobProvider: RemoteBlobProvider<TreeEntry>;\n spillPath?: string;\n options?: AbstractPFrameDriverOps;\n resolveDataInfo: DataInfoResolver<PColumnData, TreeEntry>;\n }) {\n this.logger = logger;\n\n this.localBlobProvider = localBlobProvider;\n this.remoteBlobProvider = remoteBlobProvider;\n\n this.resolveDataInfo = resolveDataInfo;\n\n this.frameConcurrencyLimiter = new ConcurrencyLimitingExecutor(options.pFrameConcurrency);\n this.tableConcurrencyLimiter = new ConcurrencyLimitingExecutor(options.pTableConcurrency);\n\n this.pFrames = new PFramePool(\n this.localBlobProvider,\n this.remoteBlobProvider,\n this.logger,\n spillPath,\n );\n this.pTableDefs = new PTableDefPool(this.logger);\n this.pTables = new PTablePool(this.pFrames, this.pTableDefs, this.logger);\n\n this.pTableCachePerFrame = new PTableCachePerFrame(this.logger, options);\n this.pTableCachePlain = new PTableCachePlain(this.logger, options);\n }\n\n async dispose(): Promise<void> {\n return await this.remoteBlobProvider[Symbol.asyncDispose]();\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n return await this.dispose();\n }\n\n //\n // Internal / Config API Methods\n //\n\n public createPFrame(def: PFrameDef<PColumn<PColumnData>>): PoolEntry<PFrameHandle> {\n const ValueTypes = new Set(Object.values(ValueType));\n\n const supportedColumns = def.filter((column) => ValueTypes.has(column.spec.valueType));\n const uniqueColumns = uniqueBy(supportedColumns, (column) => column.id);\n const columns = uniqueColumns.map((c) =>\n mapPObjectData(c, (d) => this.resolveDataInfo(c.spec, d)),\n );\n\n return this.pFrames.acquire(columns);\n }\n\n public createPTable(rawDef: PTableDef<PColumn<PColumnData>>): PoolEntry<PTableHandle> {\n const pFrameEntry = this.createPFrame(extractAllColumns(rawDef.src));\n const sortedDef = sortPTableDef(\n migrateTableFilter(\n mapPTableDef(rawDef, (c) => c.id),\n this.logger,\n ),\n );\n const pTableEntry = this.pTableDefs.acquire({\n type: \"v1\",\n def: sortedDef,\n pFrameHandle: pFrameEntry.key,\n });\n if (logPFrames()) {\n this.logger(\n \"info\",\n `Create PTable call (pFrameHandle = ${pFrameEntry.key}; pTableHandle = ${pTableEntry.key})`,\n );\n }\n\n const unref = () => {\n pTableEntry.unref();\n pFrameEntry.unref();\n };\n return {\n key: pTableEntry.key,\n resource: pTableEntry.resource,\n unref,\n [Symbol.dispose]: unref,\n };\n }\n\n public createPTableV2(def: PTableDefV2<PColumn<PColumnData>>): PoolEntry<PTableHandle> {\n const columns = uniqueBy(collectSpecQueryColumns(def.query), (c) => c.id);\n const columnsMap = columns.reduce(\n (acc, col) => ((acc[col.id] = col.spec), acc),\n {} as Record<string, PColumnSpec>,\n );\n\n const pFrameEntry = this.createPFrame(columns);\n const specFrame = createSpecFrame(columnsMap);\n const sortedQuery = sortSpecQuery(mapSpecQueryColumns(def.query, (c) => c.id));\n const { tableSpec, dataQuery } = specFrame.evaluateQuery(sortedQuery);\n\n const pTableEntry = this.pTableDefs.acquire({\n type: \"v2\",\n pFrameHandle: pFrameEntry.key,\n def: {\n tableSpec,\n dataQuery,\n },\n });\n if (logPFrames()) {\n this.logger(\n \"info\",\n `Create PTable call (pFrameHandle = ${pFrameEntry.key}; pTableHandle = ${pTableEntry.key})`,\n );\n }\n\n const unref = () => {\n pTableEntry.unref();\n pFrameEntry.unref();\n };\n return {\n key: pTableEntry.key,\n resource: pTableEntry.resource,\n unref,\n [Symbol.dispose]: unref,\n };\n }\n\n //\n // PFrame instance methods\n //\n\n public async findColumns(\n handle: PFrameHandle,\n request: FindColumnsRequest,\n ): Promise<FindColumnsResponse> {\n const iRequest: PFrameInternal.FindColumnsRequest = {\n ...request,\n compatibleWith:\n request.compatibleWith.length !== 0\n ? [\n {\n axesSpec: [\n ...new Map(\n request.compatibleWith.map((item) => [canonicalizeJson(item), item] as const),\n ).values(),\n ],\n qualifications: [],\n },\n ]\n : [],\n };\n\n const { pFramePromise } = this.pFrames.getByKey(handle);\n const pFrame = await pFramePromise;\n\n const response = await pFrame.findColumns(iRequest);\n return {\n hits: response.hits\n .filter(\n (h) =>\n // only exactly matching columns\n h.mappingVariants.length === 0 ||\n h.mappingVariants.some(\n (v) =>\n v.qualifications.forHit.length === 0 &&\n v.qualifications.forQueries.every((q) => q.length === 0),\n ),\n )\n .map((h) => h.hit),\n };\n }\n\n public async getColumnSpec(\n handle: PFrameHandle,\n columnId: PObjectId,\n ): Promise<PColumnSpec | null> {\n const { pFramePromise } = this.pFrames.getByKey(handle);\n const pFrame = await pFramePromise;\n return await pFrame.getColumnSpec(columnId);\n }\n\n public async listColumns(handle: PFrameHandle): Promise<PColumnIdAndSpec[]> {\n const { pFramePromise } = this.pFrames.getByKey(handle);\n const pFrame = await pFramePromise;\n return await pFrame.listColumns();\n }\n\n public async calculateTableData(\n handle: PFrameHandle,\n request: CalculateTableDataRequest<PObjectId>,\n range: TableRange | undefined,\n signal?: AbortSignal,\n ): Promise<CalculateTableDataResponse> {\n if (logPFrames()) {\n this.logger(\n \"info\",\n `Call calculateTableData, handle = ${handle}, request = ${JSON.stringify(request, bigintReplacer)}`,\n );\n }\n\n const table = this.pTables.acquire({\n type: \"v1\",\n pFrameHandle: handle,\n def: sortPTableDef(migrateTableFilter(request, this.logger)),\n });\n const { pTablePromise, disposeSignal } = table.resource;\n const pTable = await pTablePromise;\n\n const combinedSignal = AbortSignal.any([signal, disposeSignal].filter((s) => !!s));\n return await this.frameConcurrencyLimiter.run(async () => {\n try {\n // TODO: throw error when more then 150k rows is requested\n // after pf-plots migration to stream API\n\n const spec = pTable.getSpec();\n const data = await pTable.getData([...spec.keys()], {\n range,\n signal: combinedSignal,\n });\n\n const overallSize = await pTable.getFootprint({\n signal: combinedSignal,\n });\n this.pTableCachePerFrame.cache(table, overallSize);\n\n return spec.map((spec, i) => ({\n spec: spec,\n data: data[i],\n }));\n } catch (err: unknown) {\n table.unref();\n throw err;\n }\n });\n }\n\n public async getUniqueValues(\n handle: PFrameHandle,\n request: UniqueValuesRequest,\n signal?: AbortSignal,\n ): Promise<UniqueValuesResponse> {\n if (logPFrames()) {\n this.logger(\n \"info\",\n `Call getUniqueValues, handle = ${handle}, request = ${JSON.stringify(request, bigintReplacer)}`,\n );\n }\n\n const { pFramePromise, disposeSignal } = this.pFrames.getByKey(handle);\n const pFrame = await pFramePromise;\n\n const combinedSignal = AbortSignal.any([signal, disposeSignal].filter((s) => !!s));\n return await this.frameConcurrencyLimiter.run(async () => {\n return await pFrame.getUniqueValues(\n {\n ...request,\n filters: migrateFilters(request.filters, this.logger),\n },\n {\n signal: combinedSignal,\n },\n );\n });\n }\n\n //\n // PTable instance methods\n //\n\n public async getSpec(handle: PTableHandle): Promise<PTableColumnSpec[]> {\n const { def } = this.pTableDefs.getByKey(handle);\n using table = this.pTables.acquire(def);\n\n const { pTablePromise } = table.resource;\n const pTable = await pTablePromise;\n\n return pTable.getSpec();\n }\n\n public async getShape(handle: PTableHandle, signal?: AbortSignal): Promise<PTableShape> {\n const { def, disposeSignal: defDisposeSignal } = this.pTableDefs.getByKey(handle);\n const table = this.pTables.acquire(def);\n\n const { pTablePromise, disposeSignal } = table.resource;\n const pTable = await pTablePromise;\n\n const combinedSignal = AbortSignal.any([signal, disposeSignal].filter((s) => !!s));\n const { shape, overallSize } = await this.tableConcurrencyLimiter.run(async () => {\n const shape = await pTable.getShape({\n signal: combinedSignal,\n });\n\n const overallSize = await pTable.getFootprint({\n signal: combinedSignal,\n });\n\n return { shape, overallSize };\n });\n\n this.pTableCachePlain.cache(table, overallSize, defDisposeSignal);\n return shape;\n }\n\n public async getData(\n handle: PTableHandle,\n columnIndices: number[],\n range: TableRange | undefined,\n signal?: AbortSignal,\n ): Promise<PTableVector[]> {\n const { def, disposeSignal: defDisposeSignal } = this.pTableDefs.getByKey(handle);\n const table = this.pTables.acquire(def);\n\n const { pTablePromise, disposeSignal } = table.resource;\n const pTable = await pTablePromise;\n\n const combinedSignal = AbortSignal.any([signal, disposeSignal].filter((s) => !!s));\n const { data, overallSize } = await this.tableConcurrencyLimiter.run(async () => {\n const data = await pTable.getData(columnIndices, {\n range,\n signal: combinedSignal,\n });\n\n const overallSize = await pTable.getFootprint({\n signal: combinedSignal,\n });\n\n return { data, overallSize };\n });\n\n this.pTableCachePlain.cache(table, overallSize, defDisposeSignal);\n return data;\n }\n}\n\nfunction migrateFilters(\n filters: PTableRecordFilter[],\n logger: PFrameInternal.Logger,\n): PTableRecordFilter[] {\n const filtersV1 = [];\n const filtersV2: PTableRecordSingleValueFilterV2[] = [];\n for (const filter of filters) {\n if ((filter.type as unknown) === \"bySingleColumn\") {\n filtersV1.push(filter);\n filtersV2.push({\n ...filter,\n type: \"bySingleColumnV2\",\n });\n } else {\n filtersV2.push(filter);\n }\n }\n if (filtersV1.length > 0) {\n const filtersV1Json = JSON.stringify(filtersV1);\n logger(\n \"warn\",\n `type overwritten from 'bySingleColumn' to 'bySingleColumnV2' for filters: ${filtersV1Json}`,\n );\n }\n return filtersV2;\n}\n\nfunction migrateTableFilter<T>(\n def: Omit<PTableDef<T>, \"partitionFilters\"> | PTableDef<T>,\n logger: PFrameInternal.Logger,\n): PTableDef<T> {\n if (!(\"partitionFilters\" in def)) {\n // For old blocks assume all axes filters to be partition filters\n return {\n ...def,\n partitionFilters: migrateFilters(\n def.filters.filter((f) => f.column.type === \"axis\"),\n logger,\n ),\n filters: migrateFilters(\n def.filters.filter((f) => f.column.type === \"column\"),\n logger,\n ),\n };\n }\n return {\n ...def,\n partitionFilters: migrateFilters(def.partitionFilters, logger),\n filters: migrateFilters(def.filters, logger),\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"driver_impl.cjs","names":["PTableCachePerFrameOpsDefaults","PTableCachePlainOpsDefaults","PFrameFactory","ConcurrencyLimitingExecutor","PFramePool","PTableDefPool","PTablePool","PTableCachePerFrame","PTableCachePlain","ValueType","PoolEntryGuard","logPFrames","bigintReplacer"],"sources":["../src/driver_impl.ts"],"sourcesContent":["import {\n mapPObjectData,\n mapPTableDef,\n extractAllColumns,\n uniqueBy,\n canonicalizeJson,\n bigintReplacer,\n ValueType,\n type CalculateTableDataRequest,\n type CalculateTableDataResponse,\n type FindColumnsRequest,\n type FindColumnsResponse,\n type PColumnIdAndSpec,\n type PColumnSpec,\n type PFrameHandle,\n type PObjectId,\n type PTableColumnSpec,\n type PTableHandle,\n type PTableShape,\n type PTableVector,\n type TableRange,\n type UniqueValuesRequest,\n type UniqueValuesResponse,\n type PColumn,\n type PFrameDef,\n type PTableDef,\n type PTableRecordSingleValueFilterV2,\n type PTableRecordFilter,\n type JsonSerializable,\n type PTableDefV2,\n mapSpecQueryColumns,\n collectSpecQueryColumns,\n sortSpecQuery,\n sortPTableDef,\n resolveAnnotationParents,\n} from \"@milaboratories/pl-model-common\";\nimport type { PFrameInternal } from \"@milaboratories/pl-model-middle-layer\";\nimport {\n ConcurrencyLimitingExecutor,\n PoolEntryGuard,\n type PoolEntry,\n} from \"@milaboratories/ts-helpers\";\nimport { PFrameFactory } from \"@milaboratories/pframes-rs-node\";\nimport { tmpdir } from \"node:os\";\nimport type { AbstractInternalPFrameDriver } from \"./driver_decl\";\nimport { logPFrames } from \"./logging\";\nimport {\n PFramePool,\n type LocalBlobProvider as PoolLocalBlobProvider,\n type RemoteBlobProvider as PoolRemoteBlobProvider,\n} from \"./pframe_pool\";\nimport { PTableDefPool } from \"./ptable_def_pool\";\nimport { PTablePool } from \"./ptable_pool\";\nimport {\n PTableCachePerFrame,\n PTableCachePerFrameOpsDefaults,\n type PTableCachePerFrameOps,\n} from \"./ptable_cache_per_frame\";\nimport {\n PTableCachePlain,\n PTableCachePlainOpsDefaults,\n type PTableCachePlainOps,\n} from \"./ptable_cache_plain\";\nimport { createPFrame as createSpecFrame } from \"@milaboratories/pframes-rs-wasm\";\n\nexport interface LocalBlobProvider<TreeEntry extends JsonSerializable>\n extends PoolLocalBlobProvider<TreeEntry>, AsyncDisposable {}\n\nexport interface RemoteBlobProvider<TreeEntry extends JsonSerializable>\n extends PoolRemoteBlobProvider<TreeEntry>, AsyncDisposable {}\n\nexport type AbstractPFrameDriverOps = PTableCachePerFrameOps &\n PTableCachePlainOps & {\n /** Concurrency limits for `getUniqueValues` and `calculateTableData` requests */\n pFrameConcurrency: number;\n /** Concurrency limits for `getShape` and `getData` requests */\n pTableConcurrency: number;\n };\n\nexport const AbstractPFrameDriverOpsDefaults: AbstractPFrameDriverOps = {\n ...PTableCachePerFrameOpsDefaults,\n ...PTableCachePlainOpsDefaults,\n pFrameConcurrency: 1, // 1 join is executed in parallel and utilize all RAM and CPU cores\n pTableConcurrency: 1, // 1 joined table is read from disk at a time, which matches 1 table the user can view in the UI\n};\n\nexport type DataInfoResolver<PColumnData, TreeEntry extends JsonSerializable> = (\n spec: PColumnSpec,\n data: PColumnData,\n) => PFrameInternal.DataInfo<TreeEntry>;\n\nexport class AbstractPFrameDriver<\n PColumnData,\n TreeEntry extends JsonSerializable,\n> implements AbstractInternalPFrameDriver<PColumnData> {\n private readonly logger: PFrameInternal.Logger;\n\n private readonly localBlobProvider: LocalBlobProvider<TreeEntry>;\n private readonly remoteBlobProvider: RemoteBlobProvider<TreeEntry>;\n\n private readonly resolveDataInfo: DataInfoResolver<PColumnData, TreeEntry>;\n\n private readonly pFrames: PFramePool<TreeEntry>;\n private readonly pTableDefs: PTableDefPool;\n private readonly pTables: PTablePool<TreeEntry>;\n\n private readonly pTableCachePerFrame: PTableCachePerFrame;\n private readonly pTableCachePlain: PTableCachePlain;\n\n private readonly frameConcurrencyLimiter: ConcurrencyLimitingExecutor;\n private readonly tableConcurrencyLimiter: ConcurrencyLimitingExecutor;\n\n public async pprofDump(): Promise<Uint8Array> {\n return await PFrameFactory.pprofDump();\n }\n\n public constructor({\n logger = () => {},\n localBlobProvider,\n remoteBlobProvider,\n spillPath = tmpdir(),\n options = AbstractPFrameDriverOpsDefaults,\n resolveDataInfo,\n }: {\n logger?: PFrameInternal.Logger;\n localBlobProvider: LocalBlobProvider<TreeEntry>;\n remoteBlobProvider: RemoteBlobProvider<TreeEntry>;\n spillPath?: string;\n options?: AbstractPFrameDriverOps;\n resolveDataInfo: DataInfoResolver<PColumnData, TreeEntry>;\n }) {\n this.logger = logger;\n\n this.localBlobProvider = localBlobProvider;\n this.remoteBlobProvider = remoteBlobProvider;\n\n this.resolveDataInfo = resolveDataInfo;\n\n this.frameConcurrencyLimiter = new ConcurrencyLimitingExecutor(options.pFrameConcurrency);\n this.tableConcurrencyLimiter = new ConcurrencyLimitingExecutor(options.pTableConcurrency);\n\n this.pFrames = new PFramePool(\n this.localBlobProvider,\n this.remoteBlobProvider,\n this.logger,\n spillPath,\n );\n this.pTableDefs = new PTableDefPool(this.logger);\n this.pTables = new PTablePool(this.pFrames, this.pTableDefs, this.logger);\n\n this.pTableCachePerFrame = new PTableCachePerFrame(this.logger, options);\n this.pTableCachePlain = new PTableCachePlain(this.logger, options);\n }\n\n async dispose(): Promise<void> {\n void (await Promise.allSettled([\n this.pTables[Symbol.asyncDispose](),\n this.pTableDefs[Symbol.asyncDispose](),\n this.pFrames[Symbol.asyncDispose](),\n this.localBlobProvider[Symbol.asyncDispose](),\n this.remoteBlobProvider[Symbol.asyncDispose](),\n ]));\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n return await this.dispose();\n }\n\n //\n // Internal / Config API Methods\n //\n\n public createPFrame(def: PFrameDef<PColumn<PColumnData>>): PoolEntry<PFrameHandle> {\n const ValueTypes = new Set(Object.values(ValueType));\n const supportedColumns = def\n .filter((column) => ValueTypes.has(column.spec.valueType))\n .map((c) => ({ ...c, spec: resolveAnnotationParents(c.spec) }));\n const uniqueColumns = uniqueBy(supportedColumns, (column) => column.id);\n const columns = uniqueColumns.map((c) =>\n mapPObjectData(c, (d) => this.resolveDataInfo(c.spec, d)),\n );\n\n return this.pFrames.acquire(columns);\n }\n\n public createPTable(rawDef: PTableDef<PColumn<PColumnData>>): PoolEntry<PTableHandle> {\n using pFrameGuard = new PoolEntryGuard(this.createPFrame(extractAllColumns(rawDef.src)));\n const sortedDef = sortPTableDef(\n migrateTableFilter(\n mapPTableDef(rawDef, (c) => c.id),\n this.logger,\n ),\n );\n const pTableEntry = this.pTableDefs.acquire({\n type: \"v1\",\n def: sortedDef,\n pFrameHandle: pFrameGuard.key,\n });\n if (logPFrames()) {\n this.logger(\n \"info\",\n `Create PTable call (pFrameHandle = ${pFrameGuard.key}; pTableHandle = ${pTableEntry.key})`,\n );\n }\n\n const pFrameEntry = pFrameGuard.keep();\n const unref = () => {\n pTableEntry.unref();\n pFrameEntry.unref();\n };\n return {\n key: pTableEntry.key,\n resource: pTableEntry.resource,\n unref,\n [Symbol.dispose]: unref,\n };\n }\n\n public createPTableV2(def: PTableDefV2<PColumn<PColumnData>>): PoolEntry<PTableHandle> {\n const columns = uniqueBy(collectSpecQueryColumns(def.query), (c) => c.id);\n const columnsMap = columns.reduce(\n (acc, col) => ((acc[col.id] = col.spec), acc),\n {} as Record<string, PColumnSpec>,\n );\n\n using pFrameGuard = new PoolEntryGuard(this.createPFrame(columns));\n const ValueTypes = new Set(Object.values(ValueType));\n const specColumnsMap = Object.fromEntries(\n Object.entries(columnsMap)\n .filter(([, spec]) => ValueTypes.has(spec.valueType))\n .map(([id, spec]) => [id, resolveAnnotationParents(spec)]),\n );\n const specFrame = createSpecFrame(specColumnsMap);\n const sortedQuery = sortSpecQuery(mapSpecQueryColumns(def.query, (c) => c.id));\n const { tableSpec, dataQuery } = specFrame.evaluateQuery(sortedQuery);\n\n const pTableEntry = this.pTableDefs.acquire({\n type: \"v2\",\n pFrameHandle: pFrameGuard.key,\n def: {\n tableSpec,\n dataQuery,\n },\n });\n if (logPFrames()) {\n this.logger(\n \"info\",\n `Create PTable call (pFrameHandle = ${pFrameGuard.key}; pTableHandle = ${pTableEntry.key})`,\n );\n }\n\n const pFrameEntry = pFrameGuard.keep();\n const unref = () => {\n pTableEntry.unref();\n pFrameEntry.unref();\n };\n return {\n key: pTableEntry.key,\n resource: pTableEntry.resource,\n unref,\n [Symbol.dispose]: unref,\n };\n }\n\n //\n // PFrame instance methods\n //\n\n public async findColumns(\n handle: PFrameHandle,\n request: FindColumnsRequest,\n ): Promise<FindColumnsResponse> {\n const iRequest: PFrameInternal.FindColumnsRequest = {\n ...request,\n compatibleWith:\n request.compatibleWith.length !== 0\n ? [\n {\n axesSpec: [\n ...new Map(\n request.compatibleWith.map((item) => [canonicalizeJson(item), item] as const),\n ).values(),\n ],\n qualifications: [],\n },\n ]\n : [],\n };\n\n const { pFramePromise } = this.pFrames.getByKey(handle);\n const pFrame = await pFramePromise;\n\n const response = await pFrame.findColumns(iRequest);\n return {\n hits: response.hits\n .filter(\n (h) =>\n // only exactly matching columns\n h.mappingVariants.length === 0 ||\n h.mappingVariants.some(\n (v) =>\n v.qualifications.forHit.length === 0 &&\n v.qualifications.forQueries.every((q) => q.length === 0),\n ),\n )\n .map((h) => h.hit),\n };\n }\n\n public async getColumnSpec(\n handle: PFrameHandle,\n columnId: PObjectId,\n ): Promise<PColumnSpec | null> {\n const { pFramePromise } = this.pFrames.getByKey(handle);\n const pFrame = await pFramePromise;\n return await pFrame.getColumnSpec(columnId);\n }\n\n public async listColumns(handle: PFrameHandle): Promise<PColumnIdAndSpec[]> {\n const { pFramePromise } = this.pFrames.getByKey(handle);\n const pFrame = await pFramePromise;\n return await pFrame.listColumns();\n }\n\n public async calculateTableData(\n handle: PFrameHandle,\n request: CalculateTableDataRequest<PObjectId>,\n range: TableRange | undefined,\n signal?: AbortSignal,\n ): Promise<CalculateTableDataResponse> {\n if (logPFrames()) {\n this.logger(\n \"info\",\n `Call calculateTableData, handle = ${handle}, request = ${JSON.stringify(request, bigintReplacer)}`,\n );\n }\n\n using tableGuard = new PoolEntryGuard(\n this.pTables.acquire({\n type: \"v1\",\n pFrameHandle: handle,\n def: sortPTableDef(migrateTableFilter(request, this.logger)),\n }),\n );\n const { pTablePromise, disposeSignal } = tableGuard.resource;\n const pTable = await pTablePromise;\n\n const combinedSignal = AbortSignal.any([signal, disposeSignal].filter((s) => !!s));\n return await this.frameConcurrencyLimiter.run(async () => {\n // TODO: throw error when more then 150k rows is requested\n // after pf-plots migration to stream API\n\n const spec = pTable.getSpec();\n const data = await pTable.getData([...spec.keys()], {\n range,\n signal: combinedSignal,\n });\n\n const overallSize = await pTable.getFootprint({\n signal: combinedSignal,\n });\n this.pTableCachePerFrame.cache(tableGuard.keep(), overallSize);\n\n return spec.map((spec, i) => ({\n spec: spec,\n data: data[i],\n }));\n });\n }\n\n public async getUniqueValues(\n handle: PFrameHandle,\n request: UniqueValuesRequest,\n signal?: AbortSignal,\n ): Promise<UniqueValuesResponse> {\n if (logPFrames()) {\n this.logger(\n \"info\",\n `Call getUniqueValues, handle = ${handle}, request = ${JSON.stringify(request, bigintReplacer)}`,\n );\n }\n\n const { pFramePromise, disposeSignal } = this.pFrames.getByKey(handle);\n const pFrame = await pFramePromise;\n\n const combinedSignal = AbortSignal.any([signal, disposeSignal].filter((s) => !!s));\n return await this.frameConcurrencyLimiter.run(async () => {\n return await pFrame.getUniqueValues(\n {\n ...request,\n filters: migrateFilters(request.filters, this.logger),\n },\n {\n signal: combinedSignal,\n },\n );\n });\n }\n\n //\n // PTable instance methods\n //\n\n public async getSpec(handle: PTableHandle): Promise<PTableColumnSpec[]> {\n const { def } = this.pTableDefs.getByKey(handle);\n using table = this.pTables.acquire(def);\n\n const { pTablePromise } = table.resource;\n const pTable = await pTablePromise;\n\n return pTable.getSpec();\n }\n\n public async getShape(handle: PTableHandle, signal?: AbortSignal): Promise<PTableShape> {\n const { def, disposeSignal: defDisposeSignal } = this.pTableDefs.getByKey(handle);\n using tableGuard = new PoolEntryGuard(this.pTables.acquire(def));\n\n const { pTablePromise, disposeSignal } = tableGuard.resource;\n const pTable = await pTablePromise;\n\n const combinedSignal = AbortSignal.any([signal, disposeSignal].filter((s) => !!s));\n const { shape, overallSize } = await this.tableConcurrencyLimiter.run(async () => {\n const shape = await pTable.getShape({\n signal: combinedSignal,\n });\n\n const overallSize = await pTable.getFootprint({\n signal: combinedSignal,\n });\n\n return { shape, overallSize };\n });\n\n this.pTableCachePlain.cache(tableGuard.keep(), overallSize, defDisposeSignal);\n return shape;\n }\n\n public async getData(\n handle: PTableHandle,\n columnIndices: number[],\n range: TableRange | undefined,\n signal?: AbortSignal,\n ): Promise<PTableVector[]> {\n const { def, disposeSignal: defDisposeSignal } = this.pTableDefs.getByKey(handle);\n using tableGuard = new PoolEntryGuard(this.pTables.acquire(def));\n\n const { pTablePromise, disposeSignal } = tableGuard.resource;\n const pTable = await pTablePromise;\n\n const combinedSignal = AbortSignal.any([signal, disposeSignal].filter((s) => !!s));\n const { data, overallSize } = await this.tableConcurrencyLimiter.run(async () => {\n const data = await pTable.getData(columnIndices, {\n range,\n signal: combinedSignal,\n });\n\n const overallSize = await pTable.getFootprint({\n signal: combinedSignal,\n });\n\n return { data, overallSize };\n });\n\n this.pTableCachePlain.cache(tableGuard.keep(), overallSize, defDisposeSignal);\n return data;\n }\n}\n\nfunction migrateFilters(\n filters: PTableRecordFilter[],\n logger: PFrameInternal.Logger,\n): PTableRecordFilter[] {\n const filtersV1 = [];\n const filtersV2: PTableRecordSingleValueFilterV2[] = [];\n for (const filter of filters) {\n if ((filter.type as unknown) === \"bySingleColumn\") {\n filtersV1.push(filter);\n filtersV2.push({\n ...filter,\n type: \"bySingleColumnV2\",\n });\n } else {\n filtersV2.push(filter);\n }\n }\n if (filtersV1.length > 0) {\n const filtersV1Json = JSON.stringify(filtersV1);\n logger(\n \"warn\",\n `type overwritten from 'bySingleColumn' to 'bySingleColumnV2' for filters: ${filtersV1Json}`,\n );\n }\n return filtersV2;\n}\n\nfunction migrateTableFilter<T>(\n def: Omit<PTableDef<T>, \"partitionFilters\"> | PTableDef<T>,\n logger: PFrameInternal.Logger,\n): PTableDef<T> {\n if (!(\"partitionFilters\" in def)) {\n // For old blocks assume all axes filters to be partition filters\n return {\n ...def,\n partitionFilters: migrateFilters(\n def.filters.filter((f) => f.column.type === \"axis\"),\n logger,\n ),\n filters: migrateFilters(\n def.filters.filter((f) => f.column.type === \"column\"),\n logger,\n ),\n };\n }\n return {\n ...def,\n partitionFilters: migrateFilters(def.partitionFilters, logger),\n filters: migrateFilters(def.filters, logger),\n };\n}\n"],"mappings":"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"}
@@ -7,7 +7,7 @@ import { PoolEntry } from "@milaboratories/ts-helpers";
7
7
  import { PFrameInternal } from "@milaboratories/pl-model-middle-layer";
8
8
 
9
9
  //#region src/driver_impl.d.ts
10
- interface LocalBlobProvider<TreeEntry extends JsonSerializable> extends LocalBlobProvider$1<TreeEntry> {}
10
+ interface LocalBlobProvider<TreeEntry extends JsonSerializable> extends LocalBlobProvider$1<TreeEntry>, AsyncDisposable {}
11
11
  interface RemoteBlobProvider<TreeEntry extends JsonSerializable> extends RemoteBlobProvider$1<TreeEntry>, AsyncDisposable {}
12
12
  type AbstractPFrameDriverOps = PTableCachePerFrameOps & PTableCachePlainOps & {
13
13
  /** Concurrency limits for `getUniqueValues` and `calculateTableData` requests */pFrameConcurrency: number; /** Concurrency limits for `getShape` and `getData` requests */
@@ -5,8 +5,8 @@ import { PTablePool } from "./ptable_pool.js";
5
5
  import { PTableCachePerFrame, PTableCachePerFrameOpsDefaults } from "./ptable_cache_per_frame.js";
6
6
  import { PTableCachePlain, PTableCachePlainOpsDefaults } from "./ptable_cache_plain.js";
7
7
  import { _usingCtx } from "./_virtual/_@oxc-project_runtime@0.114.0/helpers/usingCtx.js";
8
- import { ValueType, bigintReplacer, canonicalizeJson, collectSpecQueryColumns, extractAllColumns, mapPObjectData, mapPTableDef, mapSpecQueryColumns, sortPTableDef, sortSpecQuery, uniqueBy } from "@milaboratories/pl-model-common";
9
- import { ConcurrencyLimitingExecutor } from "@milaboratories/ts-helpers";
8
+ import { ValueType, bigintReplacer, canonicalizeJson, collectSpecQueryColumns, extractAllColumns, mapPObjectData, mapPTableDef, mapSpecQueryColumns, resolveAnnotationParents, sortPTableDef, sortSpecQuery, uniqueBy } from "@milaboratories/pl-model-common";
9
+ import { ConcurrencyLimitingExecutor, PoolEntryGuard } from "@milaboratories/ts-helpers";
10
10
  import { PFrameFactory } from "@milaboratories/pframes-rs-node";
11
11
  import { tmpdir } from "node:os";
12
12
  import { createPFrame } from "@milaboratories/pframes-rs-wasm";
@@ -47,62 +47,88 @@ var AbstractPFrameDriver = class {
47
47
  this.pTableCachePlain = new PTableCachePlain(this.logger, options);
48
48
  }
49
49
  async dispose() {
50
- return await this.remoteBlobProvider[Symbol.asyncDispose]();
50
+ await Promise.allSettled([
51
+ this.pTables[Symbol.asyncDispose](),
52
+ this.pTableDefs[Symbol.asyncDispose](),
53
+ this.pFrames[Symbol.asyncDispose](),
54
+ this.localBlobProvider[Symbol.asyncDispose](),
55
+ this.remoteBlobProvider[Symbol.asyncDispose]()
56
+ ]);
51
57
  }
52
58
  async [Symbol.asyncDispose]() {
53
59
  return await this.dispose();
54
60
  }
55
61
  createPFrame(def) {
56
62
  const ValueTypes = new Set(Object.values(ValueType));
57
- const columns = uniqueBy(def.filter((column) => ValueTypes.has(column.spec.valueType)), (column) => column.id).map((c) => mapPObjectData(c, (d) => this.resolveDataInfo(c.spec, d)));
63
+ const columns = uniqueBy(def.filter((column) => ValueTypes.has(column.spec.valueType)).map((c) => ({
64
+ ...c,
65
+ spec: resolveAnnotationParents(c.spec)
66
+ })), (column) => column.id).map((c) => mapPObjectData(c, (d) => this.resolveDataInfo(c.spec, d)));
58
67
  return this.pFrames.acquire(columns);
59
68
  }
60
69
  createPTable(rawDef) {
61
- const pFrameEntry = this.createPFrame(extractAllColumns(rawDef.src));
62
- const sortedDef = sortPTableDef(migrateTableFilter(mapPTableDef(rawDef, (c) => c.id), this.logger));
63
- const pTableEntry = this.pTableDefs.acquire({
64
- type: "v1",
65
- def: sortedDef,
66
- pFrameHandle: pFrameEntry.key
67
- });
68
- if (logPFrames()) this.logger("info", `Create PTable call (pFrameHandle = ${pFrameEntry.key}; pTableHandle = ${pTableEntry.key})`);
69
- const unref = () => {
70
- pTableEntry.unref();
71
- pFrameEntry.unref();
72
- };
73
- return {
74
- key: pTableEntry.key,
75
- resource: pTableEntry.resource,
76
- unref,
77
- [Symbol.dispose]: unref
78
- };
70
+ try {
71
+ var _usingCtx$1 = _usingCtx();
72
+ const pFrameGuard = _usingCtx$1.u(new PoolEntryGuard(this.createPFrame(extractAllColumns(rawDef.src))));
73
+ const sortedDef = sortPTableDef(migrateTableFilter(mapPTableDef(rawDef, (c) => c.id), this.logger));
74
+ const pTableEntry = this.pTableDefs.acquire({
75
+ type: "v1",
76
+ def: sortedDef,
77
+ pFrameHandle: pFrameGuard.key
78
+ });
79
+ if (logPFrames()) this.logger("info", `Create PTable call (pFrameHandle = ${pFrameGuard.key}; pTableHandle = ${pTableEntry.key})`);
80
+ const pFrameEntry = pFrameGuard.keep();
81
+ const unref = () => {
82
+ pTableEntry.unref();
83
+ pFrameEntry.unref();
84
+ };
85
+ return {
86
+ key: pTableEntry.key,
87
+ resource: pTableEntry.resource,
88
+ unref,
89
+ [Symbol.dispose]: unref
90
+ };
91
+ } catch (_) {
92
+ _usingCtx$1.e = _;
93
+ } finally {
94
+ _usingCtx$1.d();
95
+ }
79
96
  }
80
97
  createPTableV2(def) {
81
- const columns = uniqueBy(collectSpecQueryColumns(def.query), (c) => c.id);
82
- const columnsMap = columns.reduce((acc, col) => (acc[col.id] = col.spec, acc), {});
83
- const pFrameEntry = this.createPFrame(columns);
84
- const specFrame = createPFrame(columnsMap);
85
- const sortedQuery = sortSpecQuery(mapSpecQueryColumns(def.query, (c) => c.id));
86
- const { tableSpec, dataQuery } = specFrame.evaluateQuery(sortedQuery);
87
- const pTableEntry = this.pTableDefs.acquire({
88
- type: "v2",
89
- pFrameHandle: pFrameEntry.key,
90
- def: {
91
- tableSpec,
92
- dataQuery
93
- }
94
- });
95
- if (logPFrames()) this.logger("info", `Create PTable call (pFrameHandle = ${pFrameEntry.key}; pTableHandle = ${pTableEntry.key})`);
96
- const unref = () => {
97
- pTableEntry.unref();
98
- pFrameEntry.unref();
99
- };
100
- return {
101
- key: pTableEntry.key,
102
- resource: pTableEntry.resource,
103
- unref,
104
- [Symbol.dispose]: unref
105
- };
98
+ try {
99
+ var _usingCtx3 = _usingCtx();
100
+ const columns = uniqueBy(collectSpecQueryColumns(def.query), (c) => c.id);
101
+ const columnsMap = columns.reduce((acc, col) => (acc[col.id] = col.spec, acc), {});
102
+ const pFrameGuard = _usingCtx3.u(new PoolEntryGuard(this.createPFrame(columns)));
103
+ const ValueTypes = new Set(Object.values(ValueType));
104
+ const specFrame = createPFrame(Object.fromEntries(Object.entries(columnsMap).filter(([, spec]) => ValueTypes.has(spec.valueType)).map(([id, spec]) => [id, resolveAnnotationParents(spec)])));
105
+ const sortedQuery = sortSpecQuery(mapSpecQueryColumns(def.query, (c) => c.id));
106
+ const { tableSpec, dataQuery } = specFrame.evaluateQuery(sortedQuery);
107
+ const pTableEntry = this.pTableDefs.acquire({
108
+ type: "v2",
109
+ pFrameHandle: pFrameGuard.key,
110
+ def: {
111
+ tableSpec,
112
+ dataQuery
113
+ }
114
+ });
115
+ if (logPFrames()) this.logger("info", `Create PTable call (pFrameHandle = ${pFrameGuard.key}; pTableHandle = ${pTableEntry.key})`);
116
+ const pFrameEntry = pFrameGuard.keep();
117
+ const unref = () => {
118
+ pTableEntry.unref();
119
+ pFrameEntry.unref();
120
+ };
121
+ return {
122
+ key: pTableEntry.key,
123
+ resource: pTableEntry.resource,
124
+ unref,
125
+ [Symbol.dispose]: unref
126
+ };
127
+ } catch (_) {
128
+ _usingCtx3.e = _;
129
+ } finally {
130
+ _usingCtx3.d();
131
+ }
106
132
  }
107
133
  async findColumns(handle, request) {
108
134
  const iRequest = {
@@ -124,33 +150,35 @@ var AbstractPFrameDriver = class {
124
150
  return await (await pFramePromise).listColumns();
125
151
  }
126
152
  async calculateTableData(handle, request, range, signal) {
127
- if (logPFrames()) this.logger("info", `Call calculateTableData, handle = ${handle}, request = ${JSON.stringify(request, bigintReplacer)}`);
128
- const table = this.pTables.acquire({
129
- type: "v1",
130
- pFrameHandle: handle,
131
- def: sortPTableDef(migrateTableFilter(request, this.logger))
132
- });
133
- const { pTablePromise, disposeSignal } = table.resource;
134
- const pTable = await pTablePromise;
135
- const combinedSignal = AbortSignal.any([signal, disposeSignal].filter((s) => !!s));
136
- return await this.frameConcurrencyLimiter.run(async () => {
137
- try {
153
+ try {
154
+ var _usingCtx4 = _usingCtx();
155
+ if (logPFrames()) this.logger("info", `Call calculateTableData, handle = ${handle}, request = ${JSON.stringify(request, bigintReplacer)}`);
156
+ const tableGuard = _usingCtx4.u(new PoolEntryGuard(this.pTables.acquire({
157
+ type: "v1",
158
+ pFrameHandle: handle,
159
+ def: sortPTableDef(migrateTableFilter(request, this.logger))
160
+ })));
161
+ const { pTablePromise, disposeSignal } = tableGuard.resource;
162
+ const pTable = await pTablePromise;
163
+ const combinedSignal = AbortSignal.any([signal, disposeSignal].filter((s) => !!s));
164
+ return await this.frameConcurrencyLimiter.run(async () => {
138
165
  const spec = pTable.getSpec();
139
166
  const data = await pTable.getData([...spec.keys()], {
140
167
  range,
141
168
  signal: combinedSignal
142
169
  });
143
170
  const overallSize = await pTable.getFootprint({ signal: combinedSignal });
144
- this.pTableCachePerFrame.cache(table, overallSize);
171
+ this.pTableCachePerFrame.cache(tableGuard.keep(), overallSize);
145
172
  return spec.map((spec, i) => ({
146
173
  spec,
147
174
  data: data[i]
148
175
  }));
149
- } catch (err) {
150
- table.unref();
151
- throw err;
152
- }
153
- });
176
+ });
177
+ } catch (_) {
178
+ _usingCtx4.e = _;
179
+ } finally {
180
+ _usingCtx4.d();
181
+ }
154
182
  }
155
183
  async getUniqueValues(handle, request, signal) {
156
184
  if (logPFrames()) this.logger("info", `Call getUniqueValues, handle = ${handle}, request = ${JSON.stringify(request, bigintReplacer)}`);
@@ -166,48 +194,62 @@ var AbstractPFrameDriver = class {
166
194
  }
167
195
  async getSpec(handle) {
168
196
  try {
169
- var _usingCtx$1 = _usingCtx();
197
+ var _usingCtx5 = _usingCtx();
170
198
  const { def } = this.pTableDefs.getByKey(handle);
171
- const { pTablePromise } = _usingCtx$1.u(this.pTables.acquire(def)).resource;
199
+ const { pTablePromise } = _usingCtx5.u(this.pTables.acquire(def)).resource;
172
200
  return (await pTablePromise).getSpec();
173
201
  } catch (_) {
174
- _usingCtx$1.e = _;
202
+ _usingCtx5.e = _;
175
203
  } finally {
176
- _usingCtx$1.d();
204
+ _usingCtx5.d();
177
205
  }
178
206
  }
179
207
  async getShape(handle, signal) {
180
- const { def, disposeSignal: defDisposeSignal } = this.pTableDefs.getByKey(handle);
181
- const table = this.pTables.acquire(def);
182
- const { pTablePromise, disposeSignal } = table.resource;
183
- const pTable = await pTablePromise;
184
- const combinedSignal = AbortSignal.any([signal, disposeSignal].filter((s) => !!s));
185
- const { shape, overallSize } = await this.tableConcurrencyLimiter.run(async () => {
186
- return {
187
- shape: await pTable.getShape({ signal: combinedSignal }),
188
- overallSize: await pTable.getFootprint({ signal: combinedSignal })
189
- };
190
- });
191
- this.pTableCachePlain.cache(table, overallSize, defDisposeSignal);
192
- return shape;
208
+ try {
209
+ var _usingCtx6 = _usingCtx();
210
+ const { def, disposeSignal: defDisposeSignal } = this.pTableDefs.getByKey(handle);
211
+ const tableGuard = _usingCtx6.u(new PoolEntryGuard(this.pTables.acquire(def)));
212
+ const { pTablePromise, disposeSignal } = tableGuard.resource;
213
+ const pTable = await pTablePromise;
214
+ const combinedSignal = AbortSignal.any([signal, disposeSignal].filter((s) => !!s));
215
+ const { shape, overallSize } = await this.tableConcurrencyLimiter.run(async () => {
216
+ return {
217
+ shape: await pTable.getShape({ signal: combinedSignal }),
218
+ overallSize: await pTable.getFootprint({ signal: combinedSignal })
219
+ };
220
+ });
221
+ this.pTableCachePlain.cache(tableGuard.keep(), overallSize, defDisposeSignal);
222
+ return shape;
223
+ } catch (_) {
224
+ _usingCtx6.e = _;
225
+ } finally {
226
+ _usingCtx6.d();
227
+ }
193
228
  }
194
229
  async getData(handle, columnIndices, range, signal) {
195
- const { def, disposeSignal: defDisposeSignal } = this.pTableDefs.getByKey(handle);
196
- const table = this.pTables.acquire(def);
197
- const { pTablePromise, disposeSignal } = table.resource;
198
- const pTable = await pTablePromise;
199
- const combinedSignal = AbortSignal.any([signal, disposeSignal].filter((s) => !!s));
200
- const { data, overallSize } = await this.tableConcurrencyLimiter.run(async () => {
201
- return {
202
- data: await pTable.getData(columnIndices, {
203
- range,
204
- signal: combinedSignal
205
- }),
206
- overallSize: await pTable.getFootprint({ signal: combinedSignal })
207
- };
208
- });
209
- this.pTableCachePlain.cache(table, overallSize, defDisposeSignal);
210
- return data;
230
+ try {
231
+ var _usingCtx7 = _usingCtx();
232
+ const { def, disposeSignal: defDisposeSignal } = this.pTableDefs.getByKey(handle);
233
+ const tableGuard = _usingCtx7.u(new PoolEntryGuard(this.pTables.acquire(def)));
234
+ const { pTablePromise, disposeSignal } = tableGuard.resource;
235
+ const pTable = await pTablePromise;
236
+ const combinedSignal = AbortSignal.any([signal, disposeSignal].filter((s) => !!s));
237
+ const { data, overallSize } = await this.tableConcurrencyLimiter.run(async () => {
238
+ return {
239
+ data: await pTable.getData(columnIndices, {
240
+ range,
241
+ signal: combinedSignal
242
+ }),
243
+ overallSize: await pTable.getFootprint({ signal: combinedSignal })
244
+ };
245
+ });
246
+ this.pTableCachePlain.cache(tableGuard.keep(), overallSize, defDisposeSignal);
247
+ return data;
248
+ } catch (_) {
249
+ _usingCtx7.e = _;
250
+ } finally {
251
+ _usingCtx7.d();
252
+ }
211
253
  }
212
254
  };
213
255
  function migrateFilters(filters, logger) {
@@ -1 +1 @@
1
- {"version":3,"file":"driver_impl.js","names":["createSpecFrame"],"sources":["../src/driver_impl.ts"],"sourcesContent":["import {\n mapPObjectData,\n mapPTableDef,\n extractAllColumns,\n uniqueBy,\n canonicalizeJson,\n bigintReplacer,\n ValueType,\n type CalculateTableDataRequest,\n type CalculateTableDataResponse,\n type FindColumnsRequest,\n type FindColumnsResponse,\n type PColumnIdAndSpec,\n type PColumnSpec,\n type PFrameHandle,\n type PObjectId,\n type PTableColumnSpec,\n type PTableHandle,\n type PTableShape,\n type PTableVector,\n type TableRange,\n type UniqueValuesRequest,\n type UniqueValuesResponse,\n type PColumn,\n type PFrameDef,\n type PTableDef,\n type PTableRecordSingleValueFilterV2,\n type PTableRecordFilter,\n type JsonSerializable,\n type PTableDefV2,\n mapSpecQueryColumns,\n collectSpecQueryColumns,\n sortSpecQuery,\n sortPTableDef,\n} from \"@milaboratories/pl-model-common\";\nimport type { PFrameInternal } from \"@milaboratories/pl-model-middle-layer\";\nimport { ConcurrencyLimitingExecutor, type PoolEntry } from \"@milaboratories/ts-helpers\";\nimport { PFrameFactory } from \"@milaboratories/pframes-rs-node\";\nimport { tmpdir } from \"node:os\";\nimport type { AbstractInternalPFrameDriver } from \"./driver_decl\";\nimport { logPFrames } from \"./logging\";\nimport {\n PFramePool,\n type LocalBlobProvider as PoolLocalBlobProvider,\n type RemoteBlobProvider as PoolRemoteBlobProvider,\n} from \"./pframe_pool\";\nimport { PTableDefPool } from \"./ptable_def_pool\";\nimport { PTablePool } from \"./ptable_pool\";\nimport {\n PTableCachePerFrame,\n PTableCachePerFrameOpsDefaults,\n type PTableCachePerFrameOps,\n} from \"./ptable_cache_per_frame\";\nimport {\n PTableCachePlain,\n PTableCachePlainOpsDefaults,\n type PTableCachePlainOps,\n} from \"./ptable_cache_plain\";\nimport { createPFrame as createSpecFrame } from \"@milaboratories/pframes-rs-wasm\";\n\nexport interface LocalBlobProvider<\n TreeEntry extends JsonSerializable,\n> extends PoolLocalBlobProvider<TreeEntry> {}\n\nexport interface RemoteBlobProvider<TreeEntry extends JsonSerializable>\n extends PoolRemoteBlobProvider<TreeEntry>, AsyncDisposable {}\n\nexport type AbstractPFrameDriverOps = PTableCachePerFrameOps &\n PTableCachePlainOps & {\n /** Concurrency limits for `getUniqueValues` and `calculateTableData` requests */\n pFrameConcurrency: number;\n /** Concurrency limits for `getShape` and `getData` requests */\n pTableConcurrency: number;\n };\n\nexport const AbstractPFrameDriverOpsDefaults: AbstractPFrameDriverOps = {\n ...PTableCachePerFrameOpsDefaults,\n ...PTableCachePlainOpsDefaults,\n pFrameConcurrency: 1, // 1 join is executed in parallel and utilize all RAM and CPU cores\n pTableConcurrency: 1, // 1 joined table is read from disk at a time, which matches 1 table the user can view in the UI\n};\n\nexport type DataInfoResolver<PColumnData, TreeEntry extends JsonSerializable> = (\n spec: PColumnSpec,\n data: PColumnData,\n) => PFrameInternal.DataInfo<TreeEntry>;\n\nexport class AbstractPFrameDriver<\n PColumnData,\n TreeEntry extends JsonSerializable,\n> implements AbstractInternalPFrameDriver<PColumnData> {\n private readonly logger: PFrameInternal.Logger;\n\n private readonly localBlobProvider: LocalBlobProvider<TreeEntry>;\n private readonly remoteBlobProvider: RemoteBlobProvider<TreeEntry>;\n\n private readonly resolveDataInfo: DataInfoResolver<PColumnData, TreeEntry>;\n\n private readonly pFrames: PFramePool<TreeEntry>;\n private readonly pTableDefs: PTableDefPool;\n private readonly pTables: PTablePool<TreeEntry>;\n\n private readonly pTableCachePerFrame: PTableCachePerFrame;\n private readonly pTableCachePlain: PTableCachePlain;\n\n private readonly frameConcurrencyLimiter: ConcurrencyLimitingExecutor;\n private readonly tableConcurrencyLimiter: ConcurrencyLimitingExecutor;\n\n public async pprofDump(): Promise<Uint8Array> {\n return await PFrameFactory.pprofDump();\n }\n\n public constructor({\n logger = () => {},\n localBlobProvider,\n remoteBlobProvider,\n spillPath = tmpdir(),\n options = AbstractPFrameDriverOpsDefaults,\n resolveDataInfo,\n }: {\n logger?: PFrameInternal.Logger;\n localBlobProvider: LocalBlobProvider<TreeEntry>;\n remoteBlobProvider: RemoteBlobProvider<TreeEntry>;\n spillPath?: string;\n options?: AbstractPFrameDriverOps;\n resolveDataInfo: DataInfoResolver<PColumnData, TreeEntry>;\n }) {\n this.logger = logger;\n\n this.localBlobProvider = localBlobProvider;\n this.remoteBlobProvider = remoteBlobProvider;\n\n this.resolveDataInfo = resolveDataInfo;\n\n this.frameConcurrencyLimiter = new ConcurrencyLimitingExecutor(options.pFrameConcurrency);\n this.tableConcurrencyLimiter = new ConcurrencyLimitingExecutor(options.pTableConcurrency);\n\n this.pFrames = new PFramePool(\n this.localBlobProvider,\n this.remoteBlobProvider,\n this.logger,\n spillPath,\n );\n this.pTableDefs = new PTableDefPool(this.logger);\n this.pTables = new PTablePool(this.pFrames, this.pTableDefs, this.logger);\n\n this.pTableCachePerFrame = new PTableCachePerFrame(this.logger, options);\n this.pTableCachePlain = new PTableCachePlain(this.logger, options);\n }\n\n async dispose(): Promise<void> {\n return await this.remoteBlobProvider[Symbol.asyncDispose]();\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n return await this.dispose();\n }\n\n //\n // Internal / Config API Methods\n //\n\n public createPFrame(def: PFrameDef<PColumn<PColumnData>>): PoolEntry<PFrameHandle> {\n const ValueTypes = new Set(Object.values(ValueType));\n\n const supportedColumns = def.filter((column) => ValueTypes.has(column.spec.valueType));\n const uniqueColumns = uniqueBy(supportedColumns, (column) => column.id);\n const columns = uniqueColumns.map((c) =>\n mapPObjectData(c, (d) => this.resolveDataInfo(c.spec, d)),\n );\n\n return this.pFrames.acquire(columns);\n }\n\n public createPTable(rawDef: PTableDef<PColumn<PColumnData>>): PoolEntry<PTableHandle> {\n const pFrameEntry = this.createPFrame(extractAllColumns(rawDef.src));\n const sortedDef = sortPTableDef(\n migrateTableFilter(\n mapPTableDef(rawDef, (c) => c.id),\n this.logger,\n ),\n );\n const pTableEntry = this.pTableDefs.acquire({\n type: \"v1\",\n def: sortedDef,\n pFrameHandle: pFrameEntry.key,\n });\n if (logPFrames()) {\n this.logger(\n \"info\",\n `Create PTable call (pFrameHandle = ${pFrameEntry.key}; pTableHandle = ${pTableEntry.key})`,\n );\n }\n\n const unref = () => {\n pTableEntry.unref();\n pFrameEntry.unref();\n };\n return {\n key: pTableEntry.key,\n resource: pTableEntry.resource,\n unref,\n [Symbol.dispose]: unref,\n };\n }\n\n public createPTableV2(def: PTableDefV2<PColumn<PColumnData>>): PoolEntry<PTableHandle> {\n const columns = uniqueBy(collectSpecQueryColumns(def.query), (c) => c.id);\n const columnsMap = columns.reduce(\n (acc, col) => ((acc[col.id] = col.spec), acc),\n {} as Record<string, PColumnSpec>,\n );\n\n const pFrameEntry = this.createPFrame(columns);\n const specFrame = createSpecFrame(columnsMap);\n const sortedQuery = sortSpecQuery(mapSpecQueryColumns(def.query, (c) => c.id));\n const { tableSpec, dataQuery } = specFrame.evaluateQuery(sortedQuery);\n\n const pTableEntry = this.pTableDefs.acquire({\n type: \"v2\",\n pFrameHandle: pFrameEntry.key,\n def: {\n tableSpec,\n dataQuery,\n },\n });\n if (logPFrames()) {\n this.logger(\n \"info\",\n `Create PTable call (pFrameHandle = ${pFrameEntry.key}; pTableHandle = ${pTableEntry.key})`,\n );\n }\n\n const unref = () => {\n pTableEntry.unref();\n pFrameEntry.unref();\n };\n return {\n key: pTableEntry.key,\n resource: pTableEntry.resource,\n unref,\n [Symbol.dispose]: unref,\n };\n }\n\n //\n // PFrame instance methods\n //\n\n public async findColumns(\n handle: PFrameHandle,\n request: FindColumnsRequest,\n ): Promise<FindColumnsResponse> {\n const iRequest: PFrameInternal.FindColumnsRequest = {\n ...request,\n compatibleWith:\n request.compatibleWith.length !== 0\n ? [\n {\n axesSpec: [\n ...new Map(\n request.compatibleWith.map((item) => [canonicalizeJson(item), item] as const),\n ).values(),\n ],\n qualifications: [],\n },\n ]\n : [],\n };\n\n const { pFramePromise } = this.pFrames.getByKey(handle);\n const pFrame = await pFramePromise;\n\n const response = await pFrame.findColumns(iRequest);\n return {\n hits: response.hits\n .filter(\n (h) =>\n // only exactly matching columns\n h.mappingVariants.length === 0 ||\n h.mappingVariants.some(\n (v) =>\n v.qualifications.forHit.length === 0 &&\n v.qualifications.forQueries.every((q) => q.length === 0),\n ),\n )\n .map((h) => h.hit),\n };\n }\n\n public async getColumnSpec(\n handle: PFrameHandle,\n columnId: PObjectId,\n ): Promise<PColumnSpec | null> {\n const { pFramePromise } = this.pFrames.getByKey(handle);\n const pFrame = await pFramePromise;\n return await pFrame.getColumnSpec(columnId);\n }\n\n public async listColumns(handle: PFrameHandle): Promise<PColumnIdAndSpec[]> {\n const { pFramePromise } = this.pFrames.getByKey(handle);\n const pFrame = await pFramePromise;\n return await pFrame.listColumns();\n }\n\n public async calculateTableData(\n handle: PFrameHandle,\n request: CalculateTableDataRequest<PObjectId>,\n range: TableRange | undefined,\n signal?: AbortSignal,\n ): Promise<CalculateTableDataResponse> {\n if (logPFrames()) {\n this.logger(\n \"info\",\n `Call calculateTableData, handle = ${handle}, request = ${JSON.stringify(request, bigintReplacer)}`,\n );\n }\n\n const table = this.pTables.acquire({\n type: \"v1\",\n pFrameHandle: handle,\n def: sortPTableDef(migrateTableFilter(request, this.logger)),\n });\n const { pTablePromise, disposeSignal } = table.resource;\n const pTable = await pTablePromise;\n\n const combinedSignal = AbortSignal.any([signal, disposeSignal].filter((s) => !!s));\n return await this.frameConcurrencyLimiter.run(async () => {\n try {\n // TODO: throw error when more then 150k rows is requested\n // after pf-plots migration to stream API\n\n const spec = pTable.getSpec();\n const data = await pTable.getData([...spec.keys()], {\n range,\n signal: combinedSignal,\n });\n\n const overallSize = await pTable.getFootprint({\n signal: combinedSignal,\n });\n this.pTableCachePerFrame.cache(table, overallSize);\n\n return spec.map((spec, i) => ({\n spec: spec,\n data: data[i],\n }));\n } catch (err: unknown) {\n table.unref();\n throw err;\n }\n });\n }\n\n public async getUniqueValues(\n handle: PFrameHandle,\n request: UniqueValuesRequest,\n signal?: AbortSignal,\n ): Promise<UniqueValuesResponse> {\n if (logPFrames()) {\n this.logger(\n \"info\",\n `Call getUniqueValues, handle = ${handle}, request = ${JSON.stringify(request, bigintReplacer)}`,\n );\n }\n\n const { pFramePromise, disposeSignal } = this.pFrames.getByKey(handle);\n const pFrame = await pFramePromise;\n\n const combinedSignal = AbortSignal.any([signal, disposeSignal].filter((s) => !!s));\n return await this.frameConcurrencyLimiter.run(async () => {\n return await pFrame.getUniqueValues(\n {\n ...request,\n filters: migrateFilters(request.filters, this.logger),\n },\n {\n signal: combinedSignal,\n },\n );\n });\n }\n\n //\n // PTable instance methods\n //\n\n public async getSpec(handle: PTableHandle): Promise<PTableColumnSpec[]> {\n const { def } = this.pTableDefs.getByKey(handle);\n using table = this.pTables.acquire(def);\n\n const { pTablePromise } = table.resource;\n const pTable = await pTablePromise;\n\n return pTable.getSpec();\n }\n\n public async getShape(handle: PTableHandle, signal?: AbortSignal): Promise<PTableShape> {\n const { def, disposeSignal: defDisposeSignal } = this.pTableDefs.getByKey(handle);\n const table = this.pTables.acquire(def);\n\n const { pTablePromise, disposeSignal } = table.resource;\n const pTable = await pTablePromise;\n\n const combinedSignal = AbortSignal.any([signal, disposeSignal].filter((s) => !!s));\n const { shape, overallSize } = await this.tableConcurrencyLimiter.run(async () => {\n const shape = await pTable.getShape({\n signal: combinedSignal,\n });\n\n const overallSize = await pTable.getFootprint({\n signal: combinedSignal,\n });\n\n return { shape, overallSize };\n });\n\n this.pTableCachePlain.cache(table, overallSize, defDisposeSignal);\n return shape;\n }\n\n public async getData(\n handle: PTableHandle,\n columnIndices: number[],\n range: TableRange | undefined,\n signal?: AbortSignal,\n ): Promise<PTableVector[]> {\n const { def, disposeSignal: defDisposeSignal } = this.pTableDefs.getByKey(handle);\n const table = this.pTables.acquire(def);\n\n const { pTablePromise, disposeSignal } = table.resource;\n const pTable = await pTablePromise;\n\n const combinedSignal = AbortSignal.any([signal, disposeSignal].filter((s) => !!s));\n const { data, overallSize } = await this.tableConcurrencyLimiter.run(async () => {\n const data = await pTable.getData(columnIndices, {\n range,\n signal: combinedSignal,\n });\n\n const overallSize = await pTable.getFootprint({\n signal: combinedSignal,\n });\n\n return { data, overallSize };\n });\n\n this.pTableCachePlain.cache(table, overallSize, defDisposeSignal);\n return data;\n }\n}\n\nfunction migrateFilters(\n filters: PTableRecordFilter[],\n logger: PFrameInternal.Logger,\n): PTableRecordFilter[] {\n const filtersV1 = [];\n const filtersV2: PTableRecordSingleValueFilterV2[] = [];\n for (const filter of filters) {\n if ((filter.type as unknown) === \"bySingleColumn\") {\n filtersV1.push(filter);\n filtersV2.push({\n ...filter,\n type: \"bySingleColumnV2\",\n });\n } else {\n filtersV2.push(filter);\n }\n }\n if (filtersV1.length > 0) {\n const filtersV1Json = JSON.stringify(filtersV1);\n logger(\n \"warn\",\n `type overwritten from 'bySingleColumn' to 'bySingleColumnV2' for filters: ${filtersV1Json}`,\n );\n }\n return filtersV2;\n}\n\nfunction migrateTableFilter<T>(\n def: Omit<PTableDef<T>, \"partitionFilters\"> | PTableDef<T>,\n logger: PFrameInternal.Logger,\n): PTableDef<T> {\n if (!(\"partitionFilters\" in def)) {\n // For old blocks assume all axes filters to be partition filters\n return {\n ...def,\n partitionFilters: migrateFilters(\n def.filters.filter((f) => f.column.type === \"axis\"),\n logger,\n ),\n filters: migrateFilters(\n def.filters.filter((f) => f.column.type === \"column\"),\n logger,\n ),\n };\n }\n return {\n ...def,\n partitionFilters: migrateFilters(def.partitionFilters, logger),\n filters: migrateFilters(def.filters, logger),\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"driver_impl.js","names":["createSpecFrame"],"sources":["../src/driver_impl.ts"],"sourcesContent":["import {\n mapPObjectData,\n mapPTableDef,\n extractAllColumns,\n uniqueBy,\n canonicalizeJson,\n bigintReplacer,\n ValueType,\n type CalculateTableDataRequest,\n type CalculateTableDataResponse,\n type FindColumnsRequest,\n type FindColumnsResponse,\n type PColumnIdAndSpec,\n type PColumnSpec,\n type PFrameHandle,\n type PObjectId,\n type PTableColumnSpec,\n type PTableHandle,\n type PTableShape,\n type PTableVector,\n type TableRange,\n type UniqueValuesRequest,\n type UniqueValuesResponse,\n type PColumn,\n type PFrameDef,\n type PTableDef,\n type PTableRecordSingleValueFilterV2,\n type PTableRecordFilter,\n type JsonSerializable,\n type PTableDefV2,\n mapSpecQueryColumns,\n collectSpecQueryColumns,\n sortSpecQuery,\n sortPTableDef,\n resolveAnnotationParents,\n} from \"@milaboratories/pl-model-common\";\nimport type { PFrameInternal } from \"@milaboratories/pl-model-middle-layer\";\nimport {\n ConcurrencyLimitingExecutor,\n PoolEntryGuard,\n type PoolEntry,\n} from \"@milaboratories/ts-helpers\";\nimport { PFrameFactory } from \"@milaboratories/pframes-rs-node\";\nimport { tmpdir } from \"node:os\";\nimport type { AbstractInternalPFrameDriver } from \"./driver_decl\";\nimport { logPFrames } from \"./logging\";\nimport {\n PFramePool,\n type LocalBlobProvider as PoolLocalBlobProvider,\n type RemoteBlobProvider as PoolRemoteBlobProvider,\n} from \"./pframe_pool\";\nimport { PTableDefPool } from \"./ptable_def_pool\";\nimport { PTablePool } from \"./ptable_pool\";\nimport {\n PTableCachePerFrame,\n PTableCachePerFrameOpsDefaults,\n type PTableCachePerFrameOps,\n} from \"./ptable_cache_per_frame\";\nimport {\n PTableCachePlain,\n PTableCachePlainOpsDefaults,\n type PTableCachePlainOps,\n} from \"./ptable_cache_plain\";\nimport { createPFrame as createSpecFrame } from \"@milaboratories/pframes-rs-wasm\";\n\nexport interface LocalBlobProvider<TreeEntry extends JsonSerializable>\n extends PoolLocalBlobProvider<TreeEntry>, AsyncDisposable {}\n\nexport interface RemoteBlobProvider<TreeEntry extends JsonSerializable>\n extends PoolRemoteBlobProvider<TreeEntry>, AsyncDisposable {}\n\nexport type AbstractPFrameDriverOps = PTableCachePerFrameOps &\n PTableCachePlainOps & {\n /** Concurrency limits for `getUniqueValues` and `calculateTableData` requests */\n pFrameConcurrency: number;\n /** Concurrency limits for `getShape` and `getData` requests */\n pTableConcurrency: number;\n };\n\nexport const AbstractPFrameDriverOpsDefaults: AbstractPFrameDriverOps = {\n ...PTableCachePerFrameOpsDefaults,\n ...PTableCachePlainOpsDefaults,\n pFrameConcurrency: 1, // 1 join is executed in parallel and utilize all RAM and CPU cores\n pTableConcurrency: 1, // 1 joined table is read from disk at a time, which matches 1 table the user can view in the UI\n};\n\nexport type DataInfoResolver<PColumnData, TreeEntry extends JsonSerializable> = (\n spec: PColumnSpec,\n data: PColumnData,\n) => PFrameInternal.DataInfo<TreeEntry>;\n\nexport class AbstractPFrameDriver<\n PColumnData,\n TreeEntry extends JsonSerializable,\n> implements AbstractInternalPFrameDriver<PColumnData> {\n private readonly logger: PFrameInternal.Logger;\n\n private readonly localBlobProvider: LocalBlobProvider<TreeEntry>;\n private readonly remoteBlobProvider: RemoteBlobProvider<TreeEntry>;\n\n private readonly resolveDataInfo: DataInfoResolver<PColumnData, TreeEntry>;\n\n private readonly pFrames: PFramePool<TreeEntry>;\n private readonly pTableDefs: PTableDefPool;\n private readonly pTables: PTablePool<TreeEntry>;\n\n private readonly pTableCachePerFrame: PTableCachePerFrame;\n private readonly pTableCachePlain: PTableCachePlain;\n\n private readonly frameConcurrencyLimiter: ConcurrencyLimitingExecutor;\n private readonly tableConcurrencyLimiter: ConcurrencyLimitingExecutor;\n\n public async pprofDump(): Promise<Uint8Array> {\n return await PFrameFactory.pprofDump();\n }\n\n public constructor({\n logger = () => {},\n localBlobProvider,\n remoteBlobProvider,\n spillPath = tmpdir(),\n options = AbstractPFrameDriverOpsDefaults,\n resolveDataInfo,\n }: {\n logger?: PFrameInternal.Logger;\n localBlobProvider: LocalBlobProvider<TreeEntry>;\n remoteBlobProvider: RemoteBlobProvider<TreeEntry>;\n spillPath?: string;\n options?: AbstractPFrameDriverOps;\n resolveDataInfo: DataInfoResolver<PColumnData, TreeEntry>;\n }) {\n this.logger = logger;\n\n this.localBlobProvider = localBlobProvider;\n this.remoteBlobProvider = remoteBlobProvider;\n\n this.resolveDataInfo = resolveDataInfo;\n\n this.frameConcurrencyLimiter = new ConcurrencyLimitingExecutor(options.pFrameConcurrency);\n this.tableConcurrencyLimiter = new ConcurrencyLimitingExecutor(options.pTableConcurrency);\n\n this.pFrames = new PFramePool(\n this.localBlobProvider,\n this.remoteBlobProvider,\n this.logger,\n spillPath,\n );\n this.pTableDefs = new PTableDefPool(this.logger);\n this.pTables = new PTablePool(this.pFrames, this.pTableDefs, this.logger);\n\n this.pTableCachePerFrame = new PTableCachePerFrame(this.logger, options);\n this.pTableCachePlain = new PTableCachePlain(this.logger, options);\n }\n\n async dispose(): Promise<void> {\n void (await Promise.allSettled([\n this.pTables[Symbol.asyncDispose](),\n this.pTableDefs[Symbol.asyncDispose](),\n this.pFrames[Symbol.asyncDispose](),\n this.localBlobProvider[Symbol.asyncDispose](),\n this.remoteBlobProvider[Symbol.asyncDispose](),\n ]));\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n return await this.dispose();\n }\n\n //\n // Internal / Config API Methods\n //\n\n public createPFrame(def: PFrameDef<PColumn<PColumnData>>): PoolEntry<PFrameHandle> {\n const ValueTypes = new Set(Object.values(ValueType));\n const supportedColumns = def\n .filter((column) => ValueTypes.has(column.spec.valueType))\n .map((c) => ({ ...c, spec: resolveAnnotationParents(c.spec) }));\n const uniqueColumns = uniqueBy(supportedColumns, (column) => column.id);\n const columns = uniqueColumns.map((c) =>\n mapPObjectData(c, (d) => this.resolveDataInfo(c.spec, d)),\n );\n\n return this.pFrames.acquire(columns);\n }\n\n public createPTable(rawDef: PTableDef<PColumn<PColumnData>>): PoolEntry<PTableHandle> {\n using pFrameGuard = new PoolEntryGuard(this.createPFrame(extractAllColumns(rawDef.src)));\n const sortedDef = sortPTableDef(\n migrateTableFilter(\n mapPTableDef(rawDef, (c) => c.id),\n this.logger,\n ),\n );\n const pTableEntry = this.pTableDefs.acquire({\n type: \"v1\",\n def: sortedDef,\n pFrameHandle: pFrameGuard.key,\n });\n if (logPFrames()) {\n this.logger(\n \"info\",\n `Create PTable call (pFrameHandle = ${pFrameGuard.key}; pTableHandle = ${pTableEntry.key})`,\n );\n }\n\n const pFrameEntry = pFrameGuard.keep();\n const unref = () => {\n pTableEntry.unref();\n pFrameEntry.unref();\n };\n return {\n key: pTableEntry.key,\n resource: pTableEntry.resource,\n unref,\n [Symbol.dispose]: unref,\n };\n }\n\n public createPTableV2(def: PTableDefV2<PColumn<PColumnData>>): PoolEntry<PTableHandle> {\n const columns = uniqueBy(collectSpecQueryColumns(def.query), (c) => c.id);\n const columnsMap = columns.reduce(\n (acc, col) => ((acc[col.id] = col.spec), acc),\n {} as Record<string, PColumnSpec>,\n );\n\n using pFrameGuard = new PoolEntryGuard(this.createPFrame(columns));\n const ValueTypes = new Set(Object.values(ValueType));\n const specColumnsMap = Object.fromEntries(\n Object.entries(columnsMap)\n .filter(([, spec]) => ValueTypes.has(spec.valueType))\n .map(([id, spec]) => [id, resolveAnnotationParents(spec)]),\n );\n const specFrame = createSpecFrame(specColumnsMap);\n const sortedQuery = sortSpecQuery(mapSpecQueryColumns(def.query, (c) => c.id));\n const { tableSpec, dataQuery } = specFrame.evaluateQuery(sortedQuery);\n\n const pTableEntry = this.pTableDefs.acquire({\n type: \"v2\",\n pFrameHandle: pFrameGuard.key,\n def: {\n tableSpec,\n dataQuery,\n },\n });\n if (logPFrames()) {\n this.logger(\n \"info\",\n `Create PTable call (pFrameHandle = ${pFrameGuard.key}; pTableHandle = ${pTableEntry.key})`,\n );\n }\n\n const pFrameEntry = pFrameGuard.keep();\n const unref = () => {\n pTableEntry.unref();\n pFrameEntry.unref();\n };\n return {\n key: pTableEntry.key,\n resource: pTableEntry.resource,\n unref,\n [Symbol.dispose]: unref,\n };\n }\n\n //\n // PFrame instance methods\n //\n\n public async findColumns(\n handle: PFrameHandle,\n request: FindColumnsRequest,\n ): Promise<FindColumnsResponse> {\n const iRequest: PFrameInternal.FindColumnsRequest = {\n ...request,\n compatibleWith:\n request.compatibleWith.length !== 0\n ? [\n {\n axesSpec: [\n ...new Map(\n request.compatibleWith.map((item) => [canonicalizeJson(item), item] as const),\n ).values(),\n ],\n qualifications: [],\n },\n ]\n : [],\n };\n\n const { pFramePromise } = this.pFrames.getByKey(handle);\n const pFrame = await pFramePromise;\n\n const response = await pFrame.findColumns(iRequest);\n return {\n hits: response.hits\n .filter(\n (h) =>\n // only exactly matching columns\n h.mappingVariants.length === 0 ||\n h.mappingVariants.some(\n (v) =>\n v.qualifications.forHit.length === 0 &&\n v.qualifications.forQueries.every((q) => q.length === 0),\n ),\n )\n .map((h) => h.hit),\n };\n }\n\n public async getColumnSpec(\n handle: PFrameHandle,\n columnId: PObjectId,\n ): Promise<PColumnSpec | null> {\n const { pFramePromise } = this.pFrames.getByKey(handle);\n const pFrame = await pFramePromise;\n return await pFrame.getColumnSpec(columnId);\n }\n\n public async listColumns(handle: PFrameHandle): Promise<PColumnIdAndSpec[]> {\n const { pFramePromise } = this.pFrames.getByKey(handle);\n const pFrame = await pFramePromise;\n return await pFrame.listColumns();\n }\n\n public async calculateTableData(\n handle: PFrameHandle,\n request: CalculateTableDataRequest<PObjectId>,\n range: TableRange | undefined,\n signal?: AbortSignal,\n ): Promise<CalculateTableDataResponse> {\n if (logPFrames()) {\n this.logger(\n \"info\",\n `Call calculateTableData, handle = ${handle}, request = ${JSON.stringify(request, bigintReplacer)}`,\n );\n }\n\n using tableGuard = new PoolEntryGuard(\n this.pTables.acquire({\n type: \"v1\",\n pFrameHandle: handle,\n def: sortPTableDef(migrateTableFilter(request, this.logger)),\n }),\n );\n const { pTablePromise, disposeSignal } = tableGuard.resource;\n const pTable = await pTablePromise;\n\n const combinedSignal = AbortSignal.any([signal, disposeSignal].filter((s) => !!s));\n return await this.frameConcurrencyLimiter.run(async () => {\n // TODO: throw error when more then 150k rows is requested\n // after pf-plots migration to stream API\n\n const spec = pTable.getSpec();\n const data = await pTable.getData([...spec.keys()], {\n range,\n signal: combinedSignal,\n });\n\n const overallSize = await pTable.getFootprint({\n signal: combinedSignal,\n });\n this.pTableCachePerFrame.cache(tableGuard.keep(), overallSize);\n\n return spec.map((spec, i) => ({\n spec: spec,\n data: data[i],\n }));\n });\n }\n\n public async getUniqueValues(\n handle: PFrameHandle,\n request: UniqueValuesRequest,\n signal?: AbortSignal,\n ): Promise<UniqueValuesResponse> {\n if (logPFrames()) {\n this.logger(\n \"info\",\n `Call getUniqueValues, handle = ${handle}, request = ${JSON.stringify(request, bigintReplacer)}`,\n );\n }\n\n const { pFramePromise, disposeSignal } = this.pFrames.getByKey(handle);\n const pFrame = await pFramePromise;\n\n const combinedSignal = AbortSignal.any([signal, disposeSignal].filter((s) => !!s));\n return await this.frameConcurrencyLimiter.run(async () => {\n return await pFrame.getUniqueValues(\n {\n ...request,\n filters: migrateFilters(request.filters, this.logger),\n },\n {\n signal: combinedSignal,\n },\n );\n });\n }\n\n //\n // PTable instance methods\n //\n\n public async getSpec(handle: PTableHandle): Promise<PTableColumnSpec[]> {\n const { def } = this.pTableDefs.getByKey(handle);\n using table = this.pTables.acquire(def);\n\n const { pTablePromise } = table.resource;\n const pTable = await pTablePromise;\n\n return pTable.getSpec();\n }\n\n public async getShape(handle: PTableHandle, signal?: AbortSignal): Promise<PTableShape> {\n const { def, disposeSignal: defDisposeSignal } = this.pTableDefs.getByKey(handle);\n using tableGuard = new PoolEntryGuard(this.pTables.acquire(def));\n\n const { pTablePromise, disposeSignal } = tableGuard.resource;\n const pTable = await pTablePromise;\n\n const combinedSignal = AbortSignal.any([signal, disposeSignal].filter((s) => !!s));\n const { shape, overallSize } = await this.tableConcurrencyLimiter.run(async () => {\n const shape = await pTable.getShape({\n signal: combinedSignal,\n });\n\n const overallSize = await pTable.getFootprint({\n signal: combinedSignal,\n });\n\n return { shape, overallSize };\n });\n\n this.pTableCachePlain.cache(tableGuard.keep(), overallSize, defDisposeSignal);\n return shape;\n }\n\n public async getData(\n handle: PTableHandle,\n columnIndices: number[],\n range: TableRange | undefined,\n signal?: AbortSignal,\n ): Promise<PTableVector[]> {\n const { def, disposeSignal: defDisposeSignal } = this.pTableDefs.getByKey(handle);\n using tableGuard = new PoolEntryGuard(this.pTables.acquire(def));\n\n const { pTablePromise, disposeSignal } = tableGuard.resource;\n const pTable = await pTablePromise;\n\n const combinedSignal = AbortSignal.any([signal, disposeSignal].filter((s) => !!s));\n const { data, overallSize } = await this.tableConcurrencyLimiter.run(async () => {\n const data = await pTable.getData(columnIndices, {\n range,\n signal: combinedSignal,\n });\n\n const overallSize = await pTable.getFootprint({\n signal: combinedSignal,\n });\n\n return { data, overallSize };\n });\n\n this.pTableCachePlain.cache(tableGuard.keep(), overallSize, defDisposeSignal);\n return data;\n }\n}\n\nfunction migrateFilters(\n filters: PTableRecordFilter[],\n logger: PFrameInternal.Logger,\n): PTableRecordFilter[] {\n const filtersV1 = [];\n const filtersV2: PTableRecordSingleValueFilterV2[] = [];\n for (const filter of filters) {\n if ((filter.type as unknown) === \"bySingleColumn\") {\n filtersV1.push(filter);\n filtersV2.push({\n ...filter,\n type: \"bySingleColumnV2\",\n });\n } else {\n filtersV2.push(filter);\n }\n }\n if (filtersV1.length > 0) {\n const filtersV1Json = JSON.stringify(filtersV1);\n logger(\n \"warn\",\n `type overwritten from 'bySingleColumn' to 'bySingleColumnV2' for filters: ${filtersV1Json}`,\n );\n }\n return filtersV2;\n}\n\nfunction migrateTableFilter<T>(\n def: Omit<PTableDef<T>, \"partitionFilters\"> | PTableDef<T>,\n logger: PFrameInternal.Logger,\n): PTableDef<T> {\n if (!(\"partitionFilters\" in def)) {\n // For old blocks assume all axes filters to be partition filters\n return {\n ...def,\n partitionFilters: migrateFilters(\n def.filters.filter((f) => f.column.type === \"axis\"),\n logger,\n ),\n filters: migrateFilters(\n def.filters.filter((f) => f.column.type === \"column\"),\n logger,\n ),\n };\n }\n return {\n ...def,\n partitionFilters: migrateFilters(def.partitionFilters, logger),\n filters: migrateFilters(def.filters, logger),\n };\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@milaboratories/pf-driver",
3
- "version": "1.2.0",
3
+ "version": "1.3.1",
4
4
  "description": "PFrameDriver implementation abstracted from Middle Layer",
5
5
  "keywords": [],
6
6
  "license": "UNLICENSED",
@@ -20,22 +20,22 @@
20
20
  }
21
21
  },
22
22
  "dependencies": {
23
- "@milaboratories/pframes-rs-node": "1.1.15",
24
- "@milaboratories/pframes-rs-wasm": "1.1.15",
23
+ "@milaboratories/pframes-rs-node": "1.1.17",
24
+ "@milaboratories/pframes-rs-wasm": "1.1.17",
25
25
  "es-toolkit": "^1.39.10",
26
26
  "lru-cache": "^11.2.2",
27
- "@milaboratories/pl-model-common": "1.29.0",
28
- "@milaboratories/pl-model-middle-layer": "1.16.0",
29
- "@milaboratories/ts-helpers": "1.7.3"
27
+ "@milaboratories/pl-model-common": "1.30.0",
28
+ "@milaboratories/ts-helpers": "1.8.0",
29
+ "@milaboratories/pl-model-middle-layer": "1.16.1"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@types/node": "~24.5.2",
33
33
  "@vitest/coverage-istanbul": "^4.0.18",
34
34
  "typescript": "~5.9.3",
35
35
  "vitest": "^4.0.18",
36
- "@milaboratories/build-configs": "1.5.2",
37
36
  "@milaboratories/ts-builder": "1.3.0",
38
- "@milaboratories/ts-configs": "1.2.2"
37
+ "@milaboratories/ts-configs": "1.2.2",
38
+ "@milaboratories/build-configs": "1.5.2"
39
39
  },
40
40
  "engines": {
41
41
  "node": ">=22.19.0"
@@ -118,6 +118,7 @@ class RemoteBlobProviderImpl implements RemoteBlobProvider<FileName> {
118
118
 
119
119
  async [Symbol.asyncDispose](): Promise<void> {
120
120
  await this.server.stop();
121
+ await this.pool[Symbol.asyncDispose]();
121
122
  }
122
123
  }
123
124
 
@@ -32,9 +32,14 @@ import {
32
32
  collectSpecQueryColumns,
33
33
  sortSpecQuery,
34
34
  sortPTableDef,
35
+ resolveAnnotationParents,
35
36
  } from "@milaboratories/pl-model-common";
36
37
  import type { PFrameInternal } from "@milaboratories/pl-model-middle-layer";
37
- import { ConcurrencyLimitingExecutor, type PoolEntry } from "@milaboratories/ts-helpers";
38
+ import {
39
+ ConcurrencyLimitingExecutor,
40
+ PoolEntryGuard,
41
+ type PoolEntry,
42
+ } from "@milaboratories/ts-helpers";
38
43
  import { PFrameFactory } from "@milaboratories/pframes-rs-node";
39
44
  import { tmpdir } from "node:os";
40
45
  import type { AbstractInternalPFrameDriver } from "./driver_decl";
@@ -58,9 +63,8 @@ import {
58
63
  } from "./ptable_cache_plain";
59
64
  import { createPFrame as createSpecFrame } from "@milaboratories/pframes-rs-wasm";
60
65
 
61
- export interface LocalBlobProvider<
62
- TreeEntry extends JsonSerializable,
63
- > extends PoolLocalBlobProvider<TreeEntry> {}
66
+ export interface LocalBlobProvider<TreeEntry extends JsonSerializable>
67
+ extends PoolLocalBlobProvider<TreeEntry>, AsyncDisposable {}
64
68
 
65
69
  export interface RemoteBlobProvider<TreeEntry extends JsonSerializable>
66
70
  extends PoolRemoteBlobProvider<TreeEntry>, AsyncDisposable {}
@@ -149,7 +153,13 @@ export class AbstractPFrameDriver<
149
153
  }
150
154
 
151
155
  async dispose(): Promise<void> {
152
- return await this.remoteBlobProvider[Symbol.asyncDispose]();
156
+ void (await Promise.allSettled([
157
+ this.pTables[Symbol.asyncDispose](),
158
+ this.pTableDefs[Symbol.asyncDispose](),
159
+ this.pFrames[Symbol.asyncDispose](),
160
+ this.localBlobProvider[Symbol.asyncDispose](),
161
+ this.remoteBlobProvider[Symbol.asyncDispose](),
162
+ ]));
153
163
  }
154
164
 
155
165
  async [Symbol.asyncDispose](): Promise<void> {
@@ -162,8 +172,9 @@ export class AbstractPFrameDriver<
162
172
 
163
173
  public createPFrame(def: PFrameDef<PColumn<PColumnData>>): PoolEntry<PFrameHandle> {
164
174
  const ValueTypes = new Set(Object.values(ValueType));
165
-
166
- const supportedColumns = def.filter((column) => ValueTypes.has(column.spec.valueType));
175
+ const supportedColumns = def
176
+ .filter((column) => ValueTypes.has(column.spec.valueType))
177
+ .map((c) => ({ ...c, spec: resolveAnnotationParents(c.spec) }));
167
178
  const uniqueColumns = uniqueBy(supportedColumns, (column) => column.id);
168
179
  const columns = uniqueColumns.map((c) =>
169
180
  mapPObjectData(c, (d) => this.resolveDataInfo(c.spec, d)),
@@ -173,7 +184,7 @@ export class AbstractPFrameDriver<
173
184
  }
174
185
 
175
186
  public createPTable(rawDef: PTableDef<PColumn<PColumnData>>): PoolEntry<PTableHandle> {
176
- const pFrameEntry = this.createPFrame(extractAllColumns(rawDef.src));
187
+ using pFrameGuard = new PoolEntryGuard(this.createPFrame(extractAllColumns(rawDef.src)));
177
188
  const sortedDef = sortPTableDef(
178
189
  migrateTableFilter(
179
190
  mapPTableDef(rawDef, (c) => c.id),
@@ -183,15 +194,16 @@ export class AbstractPFrameDriver<
183
194
  const pTableEntry = this.pTableDefs.acquire({
184
195
  type: "v1",
185
196
  def: sortedDef,
186
- pFrameHandle: pFrameEntry.key,
197
+ pFrameHandle: pFrameGuard.key,
187
198
  });
188
199
  if (logPFrames()) {
189
200
  this.logger(
190
201
  "info",
191
- `Create PTable call (pFrameHandle = ${pFrameEntry.key}; pTableHandle = ${pTableEntry.key})`,
202
+ `Create PTable call (pFrameHandle = ${pFrameGuard.key}; pTableHandle = ${pTableEntry.key})`,
192
203
  );
193
204
  }
194
205
 
206
+ const pFrameEntry = pFrameGuard.keep();
195
207
  const unref = () => {
196
208
  pTableEntry.unref();
197
209
  pFrameEntry.unref();
@@ -211,14 +223,20 @@ export class AbstractPFrameDriver<
211
223
  {} as Record<string, PColumnSpec>,
212
224
  );
213
225
 
214
- const pFrameEntry = this.createPFrame(columns);
215
- const specFrame = createSpecFrame(columnsMap);
226
+ using pFrameGuard = new PoolEntryGuard(this.createPFrame(columns));
227
+ const ValueTypes = new Set(Object.values(ValueType));
228
+ const specColumnsMap = Object.fromEntries(
229
+ Object.entries(columnsMap)
230
+ .filter(([, spec]) => ValueTypes.has(spec.valueType))
231
+ .map(([id, spec]) => [id, resolveAnnotationParents(spec)]),
232
+ );
233
+ const specFrame = createSpecFrame(specColumnsMap);
216
234
  const sortedQuery = sortSpecQuery(mapSpecQueryColumns(def.query, (c) => c.id));
217
235
  const { tableSpec, dataQuery } = specFrame.evaluateQuery(sortedQuery);
218
236
 
219
237
  const pTableEntry = this.pTableDefs.acquire({
220
238
  type: "v2",
221
- pFrameHandle: pFrameEntry.key,
239
+ pFrameHandle: pFrameGuard.key,
222
240
  def: {
223
241
  tableSpec,
224
242
  dataQuery,
@@ -227,10 +245,11 @@ export class AbstractPFrameDriver<
227
245
  if (logPFrames()) {
228
246
  this.logger(
229
247
  "info",
230
- `Create PTable call (pFrameHandle = ${pFrameEntry.key}; pTableHandle = ${pTableEntry.key})`,
248
+ `Create PTable call (pFrameHandle = ${pFrameGuard.key}; pTableHandle = ${pTableEntry.key})`,
231
249
  );
232
250
  }
233
251
 
252
+ const pFrameEntry = pFrameGuard.keep();
234
253
  const unref = () => {
235
254
  pTableEntry.unref();
236
255
  pFrameEntry.unref();
@@ -316,39 +335,36 @@ export class AbstractPFrameDriver<
316
335
  );
317
336
  }
318
337
 
319
- const table = this.pTables.acquire({
320
- type: "v1",
321
- pFrameHandle: handle,
322
- def: sortPTableDef(migrateTableFilter(request, this.logger)),
323
- });
324
- const { pTablePromise, disposeSignal } = table.resource;
338
+ using tableGuard = new PoolEntryGuard(
339
+ this.pTables.acquire({
340
+ type: "v1",
341
+ pFrameHandle: handle,
342
+ def: sortPTableDef(migrateTableFilter(request, this.logger)),
343
+ }),
344
+ );
345
+ const { pTablePromise, disposeSignal } = tableGuard.resource;
325
346
  const pTable = await pTablePromise;
326
347
 
327
348
  const combinedSignal = AbortSignal.any([signal, disposeSignal].filter((s) => !!s));
328
349
  return await this.frameConcurrencyLimiter.run(async () => {
329
- try {
330
- // TODO: throw error when more then 150k rows is requested
331
- // after pf-plots migration to stream API
350
+ // TODO: throw error when more then 150k rows is requested
351
+ // after pf-plots migration to stream API
332
352
 
333
- const spec = pTable.getSpec();
334
- const data = await pTable.getData([...spec.keys()], {
335
- range,
336
- signal: combinedSignal,
337
- });
353
+ const spec = pTable.getSpec();
354
+ const data = await pTable.getData([...spec.keys()], {
355
+ range,
356
+ signal: combinedSignal,
357
+ });
338
358
 
339
- const overallSize = await pTable.getFootprint({
340
- signal: combinedSignal,
341
- });
342
- this.pTableCachePerFrame.cache(table, overallSize);
343
-
344
- return spec.map((spec, i) => ({
345
- spec: spec,
346
- data: data[i],
347
- }));
348
- } catch (err: unknown) {
349
- table.unref();
350
- throw err;
351
- }
359
+ const overallSize = await pTable.getFootprint({
360
+ signal: combinedSignal,
361
+ });
362
+ this.pTableCachePerFrame.cache(tableGuard.keep(), overallSize);
363
+
364
+ return spec.map((spec, i) => ({
365
+ spec: spec,
366
+ data: data[i],
367
+ }));
352
368
  });
353
369
  }
354
370
 
@@ -397,9 +413,9 @@ export class AbstractPFrameDriver<
397
413
 
398
414
  public async getShape(handle: PTableHandle, signal?: AbortSignal): Promise<PTableShape> {
399
415
  const { def, disposeSignal: defDisposeSignal } = this.pTableDefs.getByKey(handle);
400
- const table = this.pTables.acquire(def);
416
+ using tableGuard = new PoolEntryGuard(this.pTables.acquire(def));
401
417
 
402
- const { pTablePromise, disposeSignal } = table.resource;
418
+ const { pTablePromise, disposeSignal } = tableGuard.resource;
403
419
  const pTable = await pTablePromise;
404
420
 
405
421
  const combinedSignal = AbortSignal.any([signal, disposeSignal].filter((s) => !!s));
@@ -415,7 +431,7 @@ export class AbstractPFrameDriver<
415
431
  return { shape, overallSize };
416
432
  });
417
433
 
418
- this.pTableCachePlain.cache(table, overallSize, defDisposeSignal);
434
+ this.pTableCachePlain.cache(tableGuard.keep(), overallSize, defDisposeSignal);
419
435
  return shape;
420
436
  }
421
437
 
@@ -426,9 +442,9 @@ export class AbstractPFrameDriver<
426
442
  signal?: AbortSignal,
427
443
  ): Promise<PTableVector[]> {
428
444
  const { def, disposeSignal: defDisposeSignal } = this.pTableDefs.getByKey(handle);
429
- const table = this.pTables.acquire(def);
445
+ using tableGuard = new PoolEntryGuard(this.pTables.acquire(def));
430
446
 
431
- const { pTablePromise, disposeSignal } = table.resource;
447
+ const { pTablePromise, disposeSignal } = tableGuard.resource;
432
448
  const pTable = await pTablePromise;
433
449
 
434
450
  const combinedSignal = AbortSignal.any([signal, disposeSignal].filter((s) => !!s));
@@ -445,7 +461,7 @@ export class AbstractPFrameDriver<
445
461
  return { data, overallSize };
446
462
  });
447
463
 
448
- this.pTableCachePlain.cache(table, overallSize, defDisposeSignal);
464
+ this.pTableCachePlain.cache(tableGuard.keep(), overallSize, defDisposeSignal);
449
465
  return data;
450
466
  }
451
467
  }