@skygraph/core 0.6.4 → 0.6.6

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.
Files changed (37) hide show
  1. package/README.md +48 -48
  2. package/dist/calendar.cjs.map +1 -1
  3. package/dist/calendar.js +1 -1
  4. package/dist/{chunk-7FA2TBSZ.js → chunk-3DDKJILC.js} +1 -1
  5. package/dist/chunk-3DDKJILC.js.map +1 -0
  6. package/dist/{chunk-GEMALROQ.js → chunk-75BQUWZC.js} +1 -1
  7. package/dist/chunk-75BQUWZC.js.map +1 -0
  8. package/dist/{chunk-ZWB7JGAJ.js → chunk-CEX4ZVZF.js} +1 -1
  9. package/dist/chunk-CEX4ZVZF.js.map +1 -0
  10. package/dist/{chunk-AB3RLBLW.js → chunk-MEZUJRC7.js} +1 -1
  11. package/dist/chunk-MEZUJRC7.js.map +1 -0
  12. package/dist/{chunk-Y7FTBBYX.js → chunk-QYUKEEBL.js} +1 -1
  13. package/dist/chunk-QYUKEEBL.js.map +1 -0
  14. package/dist/{chunk-IY6LJU3L.js → chunk-SUGXXNZK.js} +1 -1
  15. package/dist/chunk-SUGXXNZK.js.map +1 -0
  16. package/dist/form.cjs.map +1 -1
  17. package/dist/graph.cjs.map +1 -1
  18. package/dist/graph.js +1 -1
  19. package/dist/index.cjs.map +1 -1
  20. package/dist/index.js +6 -6
  21. package/dist/index.js.map +1 -1
  22. package/dist/runtime-internal.cjs.map +1 -1
  23. package/dist/runtime-internal.js +1 -1
  24. package/dist/runtime-internal.js.map +1 -1
  25. package/dist/table.cjs.map +1 -1
  26. package/dist/table.js +1 -1
  27. package/dist/tree.cjs.map +1 -1
  28. package/dist/tree.js +1 -1
  29. package/dist/virtual.cjs.map +1 -1
  30. package/dist/virtual.js +1 -1
  31. package/package.json +1 -1
  32. package/dist/chunk-7FA2TBSZ.js.map +0 -1
  33. package/dist/chunk-AB3RLBLW.js.map +0 -1
  34. package/dist/chunk-GEMALROQ.js.map +0 -1
  35. package/dist/chunk-IY6LJU3L.js.map +0 -1
  36. package/dist/chunk-Y7FTBBYX.js.map +0 -1
  37. package/dist/chunk-ZWB7JGAJ.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/engines/table/filter.ts","../src/engines/table/TableEngine.ts"],"sourcesContent":["import type {\n AdvancedFilter,\n AggregateFn,\n AggregateType,\n ColumnFilter,\n FilterOperator,\n} from './types'\n\n/**\n * Возвращает финальный оператор фильтра. Соблюдаем backward-compat:\n * если оператор не задан, и `value` — массив, считаем фильтр `in`,\n * иначе — `eq`.\n */\nexport function resolveOperator(\n filter: AdvancedFilter | ColumnFilter,\n): FilterOperator {\n const adv = filter as AdvancedFilter\n if (adv.op != null) return adv.op\n const col = filter as ColumnFilter\n if (col.operator != null) return col.operator\n return Array.isArray(filter.value) ? 'in' : 'eq'\n}\n\n/** Проверка пустоты для `isEmpty` / `isNotEmpty`. */\nfunction isEmptyValue(val: unknown): boolean {\n return val == null || val === ''\n}\n\n/** Числовое сравнение с защитой от NaN. */\nfunction asNumberPair(a: unknown, b: unknown): [number, number] | null {\n const na = typeof a === 'number' ? a : Number(a)\n const nb = typeof b === 'number' ? b : Number(b)\n if (Number.isNaN(na) || Number.isNaN(nb)) return null\n return [na, nb]\n}\n\n/**\n * Проверяет, проходит ли значение `val` фильтр (`op` + `filterValue`).\n * Используется как для `ColumnFilter`, так и для `AdvancedFilter`.\n */\nexport function matchesOperator(\n val: unknown,\n op: FilterOperator,\n filterValue: unknown,\n): boolean {\n switch (op) {\n case 'eq':\n return val === filterValue\n case 'neq':\n return val !== filterValue\n\n case 'lt':\n case 'lte':\n case 'gt':\n case 'gte': {\n const pair = asNumberPair(val, filterValue)\n if (!pair) return false\n const [a, b] = pair\n if (op === 'lt') return a < b\n if (op === 'lte') return a <= b\n if (op === 'gt') return a > b\n return a >= b\n }\n\n case 'between': {\n if (!Array.isArray(filterValue) || filterValue.length !== 2) return false\n const minPair = asNumberPair(val, filterValue[0])\n const maxPair = asNumberPair(val, filterValue[1])\n if (!minPair || !maxPair) return false\n return minPair[0] >= minPair[1] && maxPair[0] <= maxPair[1]\n }\n\n case 'in':\n return Array.isArray(filterValue) && filterValue.includes(val)\n case 'notIn':\n return Array.isArray(filterValue) && !filterValue.includes(val)\n\n case 'contains':\n if (typeof val !== 'string') return false\n return val.toLowerCase().includes(String(filterValue ?? '').toLowerCase())\n case 'startsWith':\n if (typeof val !== 'string') return false\n return val.toLowerCase().startsWith(String(filterValue ?? '').toLowerCase())\n case 'endsWith':\n if (typeof val !== 'string') return false\n return val.toLowerCase().endsWith(String(filterValue ?? '').toLowerCase())\n\n case 'isEmpty':\n return isEmptyValue(val)\n case 'isNotEmpty':\n return !isEmptyValue(val)\n }\n}\n\n/**\n * Применяет `ColumnFilter` к строке (по `filter.column`).\n * Точка входа из движка таблицы.\n */\nexport function matchesColumnFilter(\n row: Record<string, unknown>,\n filter: ColumnFilter,\n): boolean {\n const op = resolveOperator(filter)\n return matchesOperator(row[filter.column], op, filter.value)\n}\n\n/** Считает встроенную агрегацию для массива значений. */\nexport function computeAggregate(\n values: unknown[],\n type: AggregateType | AggregateFn,\n): unknown {\n if (typeof type === 'function') return type(values)\n\n if (type === 'count') return values.length\n\n const nums: number[] = []\n for (const v of values) {\n if (v == null || v === '') continue\n const n = typeof v === 'number' ? v : Number(v)\n if (!Number.isNaN(n)) nums.push(n)\n }\n if (nums.length === 0) return null\n\n switch (type) {\n case 'sum':\n return nums.reduce((a, b) => a + b, 0)\n case 'avg':\n return nums.reduce((a, b) => a + b, 0) / nums.length\n case 'min':\n return Math.min(...nums)\n case 'max':\n return Math.max(...nums)\n }\n}\n","import type { Core } from '../../types'\nimport type {\n AdvancedFilter,\n ColumnAggregate,\n ColumnFilter,\n ExportOptions,\n FilterFn,\n RowId,\n SortConfig,\n SortDirection,\n TableEngine,\n TableGroup,\n TableOptions,\n TableState,\n} from './types'\n\nimport { TABLE_PREFIX } from '../namespaces'\nimport { computeAggregate, matchesColumnFilter } from './filter'\n\nfunction statePath(tableId: string, key: string): string {\n return `${TABLE_PREFIX}${tableId}.state.${key}`\n}\n\nlet tableCounter = 0\n\n/**\n * `createTable` строит TableEngine поверх Core. Пользовательские данные строк\n * хранятся в private замыкании (`dataById`/`keysById`), а в Core попадают\n * только пути `$table.<id>.state.*` (агрегированные счётчики, ширины колонок,\n * пин-конфиг). Это держит `addRows(100k)` на масштабе O(N) Map.set вместо\n * O(N × cols) `core.set` (исторический паттерн `byId.<rid>.<col>` создавал\n * сотни тысяч узлов в Store и аллокаций Set/Map в `Core.set` на каждую\n * cell-запись — см. `docs/_streams/findings/T-Table-Perf.md` H1).\n *\n * Семантика публичных методов `getRow`/`getCell`/`getVisibleRows` сохранена.\n * Внешние подписки на `$table.<id>.state.*` пути продолжают работать;\n * подписок на `byId.*` в монорепе нет (они никогда не были задокументированы).\n */\nexport function createTable(core: Core, options?: TableOptions): TableEngine {\n const tableId = `t${tableCounter++}`\n let currentPageSize = options?.pageSize ?? 50\n\n let order: RowId[] = []\n let filteredOrder: RowId[] = []\n let sorts: SortConfig[] = []\n let filters: ColumnFilter[] = []\n let customFilterFn: FilterFn | null = null\n let page = 1\n let pinnedLeft: string[] = []\n let pinnedRight: string[] = []\n let columnWidths: Record<string, number> = {}\n\n // Группировка\n let groupByField: string | null = null\n let columnAggregates: ColumnAggregate[] = []\n let groups: TableGroup[] = []\n\n // Private storage: данные строк живут в замыкании, не в Core store.\n // Это устраняет 800k `core.set` per-cell на 100k×7 датасете и убирает\n // основной источник аллокаций (Store-узлы + Set/Map в `Core.set`).\n const dataById = new Map<RowId, Record<string, unknown>>()\n const keysById = new Map<RowId, string[]>()\n\n function getRowData(id: RowId): Record<string, unknown> | undefined {\n const stored = dataById.get(id)\n if (!stored) return undefined\n\n // Если пользователь передал явный whitelist колонок через\n // `TableOptions.columns`, отдаём отфильтрованную копию (исторический\n // контракт). В типичном кейсе (опция не задана) — возвращаем хранимую\n // ссылку без копии: hot path `compareBySort`/`recomputeFiltered`/render\n // не должны платить за per-row allocation.\n if (options?.columns) {\n const filtered: Record<string, unknown> = {}\n for (const col of options.columns) {\n filtered[col] = stored[col]\n }\n return filtered\n }\n return stored\n }\n\n function matchesFilters(rowData: Record<string, unknown>): boolean {\n if (customFilterFn && !customFilterFn(rowData)) return false\n\n for (const f of filters) {\n if (!matchesColumnFilter(rowData, f)) return false\n }\n return true\n }\n\n function compareBySort(a: RowId, b: RowId): number {\n const aData = getRowData(a)\n const bData = getRowData(b)\n\n for (const s of sorts) {\n const aVal = aData?.[s.column]\n const bVal = bData?.[s.column]\n\n if (aVal === bVal) continue\n if (aVal === undefined || aVal === null) return 1\n if (bVal === undefined || bVal === null) return -1\n\n const cmp = aVal < bVal ? -1 : 1\n return s.direction === 'asc' ? cmp : -cmp\n }\n return 0\n }\n\n function recomputeFiltered(): void {\n if (filters.length === 0 && !customFilterFn) {\n filteredOrder = [...order]\n } else {\n filteredOrder = order.filter((id) => {\n const data = getRowData(id)\n return data ? matchesFilters(data) : false\n })\n }\n\n if (sorts.length > 0) {\n filteredOrder.sort(compareBySort)\n }\n\n const totalPages = Math.max(1, Math.ceil(filteredOrder.length / currentPageSize))\n if (page > totalPages) page = totalPages\n\n recomputeGroups()\n publishState()\n }\n\n function recomputeGroups(): void {\n if (!groupByField) {\n groups = []\n return\n }\n\n const map = new Map<string, { value: unknown; rows: RowId[] }>()\n const orderKeys: string[] = []\n\n for (const id of filteredOrder) {\n const data = getRowData(id)\n if (!data) continue\n const raw = data[groupByField]\n const key = raw == null ? '__null__' : String(raw)\n if (!map.has(key)) {\n map.set(key, { value: raw, rows: [] })\n orderKeys.push(key)\n }\n map.get(key)!.rows.push(id)\n }\n\n groups = orderKeys.map((key) => {\n const { value, rows } = map.get(key)!\n const aggregates: Record<string, unknown> = {}\n for (const agg of columnAggregates) {\n const values = rows.map((id) => dataById.get(id)?.[agg.column])\n aggregates[agg.column] = computeAggregate(values, agg.type)\n }\n return { key, value, rows, aggregates }\n })\n }\n\n function publishState(): void {\n const totalPages = Math.max(1, Math.ceil(filteredOrder.length / currentPageSize))\n core.set(statePath(tableId, 'totalRows'), order.length)\n core.set(statePath(tableId, 'filteredRows'), filteredOrder.length)\n core.set(statePath(tableId, 'page'), page)\n core.set(statePath(tableId, 'pageSize'), currentPageSize)\n core.set(statePath(tableId, 'totalPages'), totalPages)\n core.set(statePath(tableId, 'groupBy'), groupByField)\n core.set(statePath(tableId, 'groupCount'), groups.length)\n }\n\n function getColumnKeys(): string[] {\n if (options?.columns) return options.columns\n if (order.length === 0) return []\n const firstId = order[0]\n return keysById.get(firstId) ?? []\n }\n\n /** Привести `AdvancedFilter | ColumnFilter` к единому `ColumnFilter`. */\n function toColumnFilter(column: string, filter: AdvancedFilter | ColumnFilter): ColumnFilter {\n const adv = filter as AdvancedFilter\n if (adv.op != null) {\n return { column, operator: adv.op, value: adv.value }\n }\n const cf = filter as ColumnFilter\n return { column, operator: cf.operator, value: cf.value }\n }\n\n const table: TableEngine = {\n addRow(id: RowId, data: Record<string, unknown>): void {\n dataById.set(id, data)\n keysById.set(id, Object.keys(data))\n order.push(id)\n recomputeFiltered()\n },\n\n addRows(rows: Array<{ id: RowId; data: Record<string, unknown> }>): void {\n // Single Map.set per row instead of (cols + 1) `core.set` per row —\n // на 100k×7 это разница 800k vs 100k операций и убирает\n // основной источник аллокаций. См. `findings/T-Table-Perf.md` H1.\n for (const row of rows) {\n dataById.set(row.id, row.data)\n keysById.set(row.id, Object.keys(row.data))\n order.push(row.id)\n }\n recomputeFiltered()\n },\n\n removeRow(id: RowId): void {\n const idx = order.indexOf(id)\n if (idx === -1) return\n order.splice(idx, 1)\n dataById.delete(id)\n keysById.delete(id)\n recomputeFiltered()\n },\n\n updateCell(id: RowId, column: string, value: unknown): void {\n const row = dataById.get(id)\n if (!row) return\n // Мутация хранимого объекта. `getRow` отдаёт эту же ссылку (см. контракт\n // в JSDoc к `createTable`), `recomputeFiltered` снизу пересоберёт сорт/\n // группы как раньше.\n row[column] = value\n const keys = keysById.get(id)\n if (keys && !keys.includes(column)) {\n keys.push(column)\n }\n recomputeFiltered()\n },\n\n getRow(id: RowId): Record<string, unknown> | undefined {\n return getRowData(id)\n },\n\n getCell(id: RowId, column: string): unknown {\n return dataById.get(id)?.[column]\n },\n\n getVisibleRows(): Array<{ id: RowId; data: Record<string, unknown> }> {\n const start = (page - 1) * currentPageSize\n const end = start + currentPageSize\n const slice = filteredOrder.slice(start, end)\n const out = new Array(slice.length) as Array<{\n id: RowId\n data: Record<string, unknown>\n }>\n for (let i = 0; i < slice.length; i++) {\n const id = slice[i]\n out[i] = { id, data: getRowData(id) ?? {} }\n }\n return out\n },\n\n getAllRowIds(): RowId[] {\n return [...order]\n },\n\n getAllRows(): Array<{ id: RowId; data: Record<string, unknown> }> {\n const out = new Array(filteredOrder.length) as Array<{\n id: RowId\n data: Record<string, unknown>\n }>\n for (let i = 0; i < filteredOrder.length; i++) {\n const id = filteredOrder[i]\n out[i] = { id, data: getRowData(id) ?? {} }\n }\n return out\n },\n\n setSort(column: string, direction: SortDirection, append?: boolean): void {\n if (append) {\n sorts = sorts.filter((s) => s.column !== column)\n sorts.push({ column, direction })\n } else {\n sorts = [{ column, direction }]\n }\n recomputeFiltered()\n },\n\n setSorts(newSorts: SortConfig[]): void {\n sorts = [...newSorts]\n recomputeFiltered()\n },\n\n clearSort(): void {\n sorts = []\n recomputeFiltered()\n },\n\n addFilter(filter: ColumnFilter): void {\n filters = filters.filter((f) => f.column !== filter.column)\n filters.push(filter)\n page = 1\n recomputeFiltered()\n },\n\n removeFilter(column: string): void {\n filters = filters.filter((f) => f.column !== column)\n recomputeFiltered()\n },\n\n clearFilters(): void {\n filters = []\n customFilterFn = null\n recomputeFiltered()\n },\n\n setFilterFn(fn: FilterFn | null): void {\n customFilterFn = fn\n recomputeFiltered()\n },\n\n setColumnFilter(column, filter): void {\n filters = filters.filter((f) => f.column !== column)\n if (filter !== null) {\n filters.push(toColumnFilter(column, filter))\n }\n page = 1\n recomputeFiltered()\n },\n\n setPage(p: number): void {\n const totalPages = Math.max(1, Math.ceil(filteredOrder.length / currentPageSize))\n page = Math.max(1, Math.min(p, totalPages))\n publishState()\n },\n\n setPageSize(size: number): void {\n currentPageSize = size\n page = 1\n recomputeFiltered()\n },\n\n nextPage(): void {\n table.setPage(page + 1)\n },\n\n prevPage(): void {\n table.setPage(page - 1)\n },\n\n moveRow(fromIndex: number, toIndex: number): void {\n if (fromIndex < 0 || fromIndex >= order.length) return\n if (toIndex < 0 || toIndex >= order.length) return\n if (fromIndex === toIndex) return\n\n const [item] = order.splice(fromIndex, 1)\n order.splice(toIndex, 0, item)\n recomputeFiltered()\n },\n\n pinColumn(column: string, side: 'left' | 'right' | null): void {\n pinnedLeft = pinnedLeft.filter((c) => c !== column)\n pinnedRight = pinnedRight.filter((c) => c !== column)\n if (side === 'left') pinnedLeft.push(column)\n else if (side === 'right') pinnedRight.push(column)\n core.set(statePath(tableId, 'pinnedLeft'), [...pinnedLeft])\n core.set(statePath(tableId, 'pinnedRight'), [...pinnedRight])\n },\n\n getPinnedColumns(): { left: string[]; right: string[] } {\n return { left: [...pinnedLeft], right: [...pinnedRight] }\n },\n\n clearPinned(): void {\n pinnedLeft = []\n pinnedRight = []\n core.set(statePath(tableId, 'pinnedLeft'), [])\n core.set(statePath(tableId, 'pinnedRight'), [])\n },\n\n setColumnWidth(column: string, width: number): void {\n columnWidths = { ...columnWidths, [column]: width }\n core.set(statePath(tableId, 'columnWidths'), { ...columnWidths })\n },\n\n getColumnWidth(column: string): number | undefined {\n return columnWidths[column]\n },\n\n getColumnWidths(): Record<string, number> {\n return { ...columnWidths }\n },\n\n clearColumnWidths(): void {\n columnWidths = {}\n core.set(statePath(tableId, 'columnWidths'), {})\n },\n\n moveRows(ids: RowId[], toIndex: number): void {\n const items = ids\n .map((id) => {\n const idx = order.indexOf(id)\n return { id, idx }\n })\n .filter((x) => x.idx !== -1)\n\n if (items.length === 0) return\n\n const idsSet = new Set(ids)\n const remaining = order.filter((id) => !idsSet.has(id))\n const clamped = Math.max(0, Math.min(toIndex, remaining.length))\n remaining.splice(clamped, 0, ...items.map((x) => x.id))\n order = remaining\n recomputeFiltered()\n },\n\n getExportData(exportOptions?: ExportOptions): string[][] {\n const cols = exportOptions?.columns ?? getColumnKeys()\n const result: string[][] = []\n\n if (exportOptions?.headers !== false) {\n result.push(cols)\n }\n\n const sourceIds = exportOptions?.allRows\n ? filteredOrder\n : filteredOrder.slice(\n (page - 1) * currentPageSize,\n (page - 1) * currentPageSize + currentPageSize,\n )\n\n for (const id of sourceIds) {\n const data = getRowData(id)\n if (!data) continue\n result.push(\n cols.map((col) => {\n const v = data[col]\n return v == null ? '' : String(v)\n }),\n )\n }\n\n return result\n },\n\n getTableState(): TableState {\n const totalPages = Math.max(1, Math.ceil(filteredOrder.length / currentPageSize))\n return {\n totalRows: order.length,\n filteredRows: filteredOrder.length,\n page,\n pageSize: currentPageSize,\n totalPages,\n sorts: [...sorts],\n sort: sorts.length > 0 ? sorts[0] : null,\n filters: [...filters],\n groupBy: groupByField,\n groupCount: groups.length,\n }\n },\n\n groupBy(field, aggregates): void {\n groupByField = field ?? null\n columnAggregates = aggregates ? [...aggregates] : []\n recomputeGroups()\n publishState()\n },\n\n clearGroupBy(): void {\n groupByField = null\n columnAggregates = []\n groups = []\n publishState()\n },\n\n getGroupBy(): string | null {\n return groupByField\n },\n\n getGroups(): TableGroup[] {\n return groups.map((g) => ({\n key: g.key,\n value: g.value,\n rows: [...g.rows],\n aggregates: { ...g.aggregates },\n }))\n },\n\n getEstimatedRowHeight(id: RowId): number | null {\n const fn = options?.estimateRowHeight\n if (!fn) return null\n const data = getRowData(id)\n if (!data) return null\n const v = fn(data, id)\n return Number.isFinite(v) ? v : null\n },\n\n reset(): void {\n order = []\n filteredOrder = []\n sorts = []\n filters = []\n customFilterFn = null\n page = 1\n pinnedLeft = []\n pinnedRight = []\n columnWidths = {}\n groupByField = null\n columnAggregates = []\n groups = []\n dataById.clear()\n keysById.clear()\n core.set(statePath(tableId, 'columnWidths'), {})\n publishState()\n },\n }\n\n // Initial publish — emit empty `columnWidths` so subscribers can read a\n // stable shape from the store without needing to handle `undefined`.\n core.set(statePath(tableId, 'columnWidths'), {})\n publishState()\n return table\n}\n"],"mappings":"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","names":[]}