import type { Effect, Stream } from 'effect'; import type { AnyEntityESchema, AnyUnkeyedESchema, } from '../../../eschema/index.js'; import type { ChangeNotice, DecodedEntity, DecodedSingleEntity, } from '../../../core/index.js'; import type { SnapshotIncompatible } from '../../../snapshot/index.js'; import type { DatabaseError } from '../error/index.js'; import type { EncodedItem, StdTableService } from '../contract/index.js'; import { Table as DefinitionTable, type GlobalSecondaryIndex, type GlobalSecondaryIndexMap, type LocalSecondaryIndex, type LocalSecondaryIndexMap, type PrimaryIndex, type TableBuilder as DefinitionTableBuilder, type TableDefinition as DefinitionTableDefinition, type TableTopologyBuilder as DefinitionTopologyBuilder, } from '../definition/index.js'; import type { AnyTransactOp, KeyedBuilderStart, SingleBuilder, TableEffect, TransactOp, } from '../entity/index.js'; import { decorateTable } from './decoration.js'; export interface ScanOptions { readonly parallelism?: number; } export interface DriftResult { readonly drifted: boolean; readonly currentForm: EncodedItem; } type TableStream = Stream.Stream< A, DatabaseError, StdTableService >; export interface StdTable< Name extends string = string, Primary extends PrimaryIndex = PrimaryIndex, Lsis extends LocalSecondaryIndexMap = LocalSecondaryIndexMap, Gsis extends GlobalSecondaryIndexMap = GlobalSecondaryIndexMap, > { readonly logicalName: Name; readonly primary: Primary; readonly localSecondaryIndexes: Lsis; readonly globalSecondaryIndexes: Gsis; readonly registeredEntities: DefinitionTableDefinition['registeredEntities']; snapshot(): ReturnType['snapshot']>; entity( schema: S, ): KeyedBuilderStart; singleEntity(schema: S): SingleBuilder; transact[]>( ops: Ops, ): TableEffect< { readonly [K in keyof Ops]: Ops[K] extends { readonly operationKind: 'checkOp'; } ? null : Ops[K] extends TransactOp ? DecodedEntity | DecodedSingleEntity : never; }, Name >; dangerouslyRemoveAllItems( confirmation: 'I KNOW WHAT I AM DOING', ): TableEffect<{ readonly itemsDeleted: number }, Name>; subscribe(): Stream.Stream; scan(options?: ScanOptions): TableStream; drift(item: EncodedItem): TableEffect; reindex(currentForm: EncodedItem): TableEffect; verifySnapshot(): Effect.Effect< void, DatabaseError | SnapshotIncompatible, StdTableService >; } export interface TableBuilder { readonly logicalName: Name; primary( pk: Pk, sk: Sk, ): TopologyBuilder, {}, {}>; } export interface TopologyBuilder< Name extends string, Primary extends PrimaryIndex, Lsis extends LocalSecondaryIndexMap, Gsis extends GlobalSecondaryIndexMap, > { lsi( name: Slot, sk: Sk, ): TopologyBuilder< Name, Primary, Lsis & Record>, Gsis >; gsi( name: Slot, pk: Pk, sk: Sk, ): TopologyBuilder< Name, Primary, Lsis, Gsis & Record> >; build(): StdTable; } const wrapTopology = < Name extends string, Primary extends PrimaryIndex, Lsis extends LocalSecondaryIndexMap, Gsis extends GlobalSecondaryIndexMap, >( builder: DefinitionTopologyBuilder, ): TopologyBuilder => ({ lsi(name: Slot, sk: Sk) { return wrapTopology(builder.lsi(name, sk)); }, gsi( name: Slot, pk: Pk, sk: Sk, ) { return wrapTopology(builder.gsi(name, pk, sk)); }, build() { return decorateTable(builder.build()) as StdTable< Name, Primary, Lsis, Gsis >; }, }); export const StdTable = { make(name: Name): TableBuilder { const builder = DefinitionTable.make( name as never, ) as DefinitionTableBuilder; return { logicalName: name, primary(pk, sk) { return wrapTopology(builder.primary(pk, sk)); }, }; }, };