import { SourceState } from '@wix/bex-core'; import type { SchemaSource } from '@wix/bex-core'; import type { FieldsSourceProvider } from '../fieldsSourceProvider'; import type { ToolbarCollectionState } from '../../state'; import { SchemaState } from './SchemaState'; /** * A schema source ready to attach to a table: the full config plus a * `setOnTable` that builds the SchemaState. Keeping `new SchemaState` here — not * in the table hook — keeps it out of the core table bundle; only consumers that * call `tableSchemaSource` pull it in. * * `schemaState` exposes the attached state so the import reads the same * live schema the table renders — import always matches the visible columns * (including fields it just created, or ones added via the field-management * panel), rather than a separate loaded copy. */ export type TableSchemaSource> = SchemaSource & FieldsSourceProvider & { readonly schemaState?: SchemaState; }; /** * Implemented as a class (not an object literal with a `get schemaState()` after * `...source`): a getter placed in a spread literal is evaluated once and * flattened to a static `undefined` data property by Object.assign-based (loose) * object-spread transpilation, which silently drops the live binding — so * the import would never see the loaded fields. A prototype accessor is * always a real accessor, immune to that. * * The wrapped source's members (`collectionConfig`, `loadSchema`, …) are copied * onto the instance so it's usable anywhere a `SchemaSource` is; `state` is * created once on attach and reused, so the table and the import share * one SchemaState (and one load). */ class TableSchemaSourceImpl implements TableSchemaSource { private state?: SchemaState; private readonly source: SchemaSource; // A field + body assignment (not a constructor parameter property — the docs // Storybook's Babel doesn't strip that TS syntax). constructor(source: SchemaSource) { this.source = source; } // Delegate the SchemaSource surface to the wrapped source via getters, so the // instance always reflects it with no copies to keep in sync. Prototype // accessors (unlike a getter inside a `...source` spread literal) survive // Object.assign-based (loose) object-spread transpilation. get collectionId() { return this.source.collectionId; } get paginationMode() { return this.source.paginationMode; } get itemKey() { return this.source.itemKey; } get itemName() { return this.source.itemName; } get getFieldValue() { return this.source.getFieldValue; } get setFieldValue() { return this.source.setFieldValue; } get references() { return this.source.references; } get creatableFieldTypes() { return this.source.creatableFieldTypes; } get fieldPermissions() { return this.source.fieldPermissions; } get supportsPii() { return this.source.supportsPii; } get loadSchema() { return this.source.loadSchema; } get searchableFieldIds() { return this.source.searchableFieldIds; } get canAddFields() { return this.source.canAddFields; } get canEditField() { return this.source.canEditField; } get canDeleteField() { return this.source.canDeleteField; } get schemaState(): SchemaState | undefined { return this.state; } setOnTable(toolbar: ToolbarCollectionState): void { this.state ??= new SchemaState({ sourceState: new SourceState({ container: toolbar.container, source: this.source, }), }); this.state.setOnTable(toolbar); } } /** @deprecated Pass the source to a `@wix/patterns/schema` collection hook * instead — no wrapper needed. */ export const tableSchemaSource = ( source: SchemaSource, ): TableSchemaSource => new TableSchemaSourceImpl(source);