{"_id":"@brios-sorzu/core","_rev":"4-7df2c8f86c8cdfd2894c63f0ffab3b7f","name":"@brios-sorzu/core","dist-tags":{"latest":"0.1.3"},"versions":{"0.1.0":{"name":"@brios-sorzu/core","version":"0.1.0","license":"MIT","_id":"@brios-sorzu/core@0.1.0","maintainers":[{"name":"briaansz","email":"briaansorzu@gmail.com"}],"dist":{"shasum":"812a92a582ca8ff5d25243bbd07250787a39d2a1","tarball":"https://registry.npmjs.org/@brios-sorzu/core/-/core-0.1.0.tgz","fileCount":13,"integrity":"sha512-i8fsGcVl0Zx8DbsoAO219jUUorxBiV1UzF7d7eHgY0yVyIrqhTphxyiEywLB9auYvkm2LyPxvGqjln9uwFBrOA==","signatures":[{"sig":"MEQCIFmWZhHyLDtRlf65SWEiVw3lozIsd2Tsbs3zs7Vs9/BKAiAJWTL7geeUS2u0F83aix/cgn6K57mp6pOAARAwxN/iCQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":97642},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"_npmUser":{"name":"briaansz","email":"briaansorzu@gmail.com"},"description":"Núcleo independiente de Brios Grid","directories":{},"sideEffects":false,"_nodeVersion":"24.15.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/core_0.1.0_1786294127304_0.7413740610492017","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@brios-sorzu/core","version":"0.1.1","license":"MIT","_id":"@brios-sorzu/core@0.1.1","maintainers":[{"name":"briaansz","email":"briaansorzu@gmail.com"}],"dist":{"shasum":"6141ad765667f7f3fefa6386f10f82f87e93be70","tarball":"https://registry.npmjs.org/@brios-sorzu/core/-/core-0.1.1.tgz","fileCount":12,"integrity":"sha512-Zd4iziRZ3OyqjpN3V4ortnjMFJQxJG3LysopXbnGfa7AbtAIekIwNN3t+BDxMufnM9SJm137Vkfn3tvxayONSQ==","signatures":[{"sig":"MEQCIHy9G9rN4v64LBN5Z5Qt01NhMvX72roJBne+osb17RisAiBKGN0S1Em1/U06nUE22UsEOGsrymuzjXbDxLfdTbNPYA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":96565},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"587119c03453a46f32193e678096d59cd9f70fa9","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:241359a8-a957-406c-8019-171619559d49"}},"_npmVersion":"11.16.0","description":"Núcleo independiente de Brios Grid","directories":{},"sideEffects":false,"_nodeVersion":"24.18.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/core_0.1.1_1786386775854_0.05630852043742163","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@brios-sorzu/core","version":"0.1.2","license":"MIT","_id":"@brios-sorzu/core@0.1.2","maintainers":[{"name":"briaansz","email":"briaansorzu@gmail.com"}],"dist":{"shasum":"0b766c5d87d011973581b5f94ece2a6c56a7194e","tarball":"https://registry.npmjs.org/@brios-sorzu/core/-/core-0.1.2.tgz","fileCount":12,"integrity":"sha512-dVe1UyZmcrz5L0XmG3/82HYMk9Ou/vydWktkWc58llE9jGfid+EanJ02r8swvgYPScI9Xn/28V3kq/Jvv/OBjg==","signatures":[{"sig":"MEYCIQCV2c2emPzQoO15bXsb4qj5c5TYJtSh5tT8Ohq0Vtq2QAIhAKeKFO3FVtSHPluaG710qhEunaSKO+p0w4EXzzu0uK98","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":96671},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"8377654fdb7565c507c28ab95b8e8722185ecf0e","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:241359a8-a957-406c-8019-171619559d49"}},"_npmVersion":"11.16.0","description":"Núcleo independiente de Brios Grid","directories":{},"sideEffects":false,"_nodeVersion":"24.18.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/core_0.1.2_1786417434506_0.5571864109053004","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@brios-sorzu/core","version":"0.1.3","description":"Núcleo independiente de Brios Grid","type":"module","main":"./dist/index.js","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"sideEffects":false,"license":"MIT","publishConfig":{"access":"public"},"_id":"@brios-sorzu/core@0.1.3","_nodeVersion":"24.18.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-ipm4I6cvtA1GP2CJ+B7gmrBJN8lviD2uydYZd+r05rHM8dDFCCGTHlaz2Km75U3aXorLl3PVGNa8RH+YxmEOBg==","shasum":"4b4ae5e63ba03c3f28af7403289c480d7faac174","tarball":"https://registry.npmjs.org/@brios-sorzu/core/-/core-0.1.3.tgz","fileCount":12,"unpackedSize":96888,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIC6pd1ViwiDbOFU2EdRiQbXHI1WgBo9/zihNAdcqCnIKAiAfdClx6g9O8Aux+78HBdGMsplaH11Gf+hZFY7Ybdfvlw=="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:241359a8-a957-406c-8019-171619559d49"}},"directories":{},"maintainers":[{"name":"briaansz","email":"briaansorzu@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/core_0.1.3_1786498504368_0.5385870237685852"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-09T16:48:46.865Z","modified":"2026-08-12T01:35:04.678Z","0.1.0":"2026-08-09T16:48:47.472Z","0.1.1":"2026-08-10T18:32:56.008Z","0.1.2":"2026-08-11T03:03:54.689Z","0.1.3":"2026-08-12T01:35:04.509Z"},"license":"MIT","description":"Núcleo independiente de Brios Grid","maintainers":[{"name":"briaansz","email":"briaansorzu@gmail.com"}],"readme":"# @brios-sorzu/core\n\nNúcleo independiente de framework para Brios Grid.\n\nIncluye `GridController`, selección, filtros, ordenamiento, agrupamiento, TreeGrid,\nfórmulas, validación, undo/redo y contratos de fuentes de datos.\n\nPara actualizar colecciones con identidad estable, `applyDataDiff(next)` compara las\nclaves definidas por `getRowId` y devuelve `added`, `updated` y `removed` sin reiniciar\nel historial ni el estado de selección.\n\nLa política de referencias es explícita: una fila con la misma clave y una referencia\nde objeto nueva se reporta como `updated`; una mutación sobre la misma referencia no se\nreporta como cambio de diff. Para hacer visible una mutación usa `setData()` o, de\npreferencia, crea una nueva referencia de fila. Sin `getRowId`, la identidad cae al\níndice y no debe usarse para reordenamientos o inserciones.\n\n## Fuente remota con cache y prefetch\n\n```ts\nimport { GridController, withGridDataCache } from '@brios-sorzu/core';\n\nconst dataSource = withGridDataCache({\n  async load(query, signal) {\n    const response = await fetch('/api/customers?' + new URLSearchParams({ page: String(query.page) }), { signal });\n    return await response.json();\n  }\n});\n\nconst grid = new GridController({ columns, dataSource });\nawait grid.load();\nawait grid.prefetch({ page: grid.page + 1 });\n```\n\nLas cargas remotas pueden reintentarse con backoff y clasificación de errores:\n\n```ts\nconst grid = new GridController({\n  columns,\n  dataSource,\n  retry: {\n    retries: 2,\n    delayMs: 250,\n    backoff: 2,\n    shouldRetry: (error) => error instanceof TypeError\n  }\n});\n```\n\n`setDataSource()` cancela la solicitud anterior. En integraciones manuales, llama a\n`grid.dispose()` al destruir el host para cancelar cualquier carga pendiente.\n\n`withGridDataCache` proporciona TTL, límite LRU, deduplicación de cargas,\n`getCached`, `invalidate` y limpieza automática después de mutaciones CRUD. Con\n`{ staleWhileRevalidate: true }`, una entrada vencida se devuelve inmediatamente\nmientras se refresca en segundo plano.\n\n`grid.remoteState` expone `loading`, `error`, `empty`, `total`, `requestId` y\n`lastUpdated` y `nextCursor` para construir estados de loading, error, empty y\npaginación cursor en cualquier framework. Usa `grid.loadNextCursor()` para avanzar\ncuando el datasource devuelve `nextCursor`.\n\nEl contrato remoto recibe un `GridQuery` con `page`, `pageSize`, `cursor`, `sort`,\n`filters`, `filterGroups`, `groups` y `search`, y devuelve un `GridResult` con\n`items`, `total`, opcionalmente `hasMore` y `nextCursor`. El `AbortSignal` debe ser\nrespetado por el adaptador; una respuesta cancelada u obsoleta no reemplaza las filas\nactuales.\n\nUn datasource puede reconciliar un rechazo de edición (por ejemplo, un conflicto de\nversión HTTP 409) con `resolveConflict`. El callback recibe `key`, `row`, `changes` y\n`error`; debe devolver la fila aceptada por el servidor o `null` para conservar el\nrollback/error normal:\n\n```ts\nconst source: GridDataSource<Row> = {\n  load,\n  update,\n  resolveConflict: async ({ row, changes, error }) => {\n    if ((error as { status?: number }).status !== 409) return null;\n    return { ...row, ...changes, version: await getLatestVersion() };\n  }\n};\n```\n\nLa misma resolución se aplica por fila cuando `updateMany` rechaza una edición masiva:\nel controlador invoca `resolveConflict` para cada clave. Si todas se reconcilian, confirma\nel batch; si solo algunas lo hacen, aplica esas filas y lanza\n`GridRemotePartialConflictError` con `resolved` y `conflicts`, dejando que la UI haga un\nrollback selectivo. Si ninguna se reconcilia, conserva el error original.\n\nPara serializar el estado de consulta en URLs o storage:\n\n```ts\nimport { parseGridQueryState, serializeGridQueryState } from '@brios-sorzu/core';\n\nconst encoded = serializeGridQueryState(grid.query());\nconst restored = parseGridQueryState(encoded);\n```\n\nEl parser valida la versión y devuelve `null` ante entradas corruptas.\n\n## Actualizaciones en tiempo real\n\n`GridRealtimeSource` es un contrato estructural compatible con Observables y\nadaptadores de WebSocket:\n\n```ts\ngrid.setRealtimeSource({\n  subscribe(next) {\n    socket.onmessage = (event) => next(JSON.parse(event.data));\n    return () => socket.close();\n  }\n});\n```\n\nLos eventos admitidos son `insert`, `update`, `remove` y `reset`. La suscripción se\nlimpia automáticamente con `dispose()` o al reemplazarla.\n\nReact y Vue no forman parte de la versión Angular actual; el core no depende de ningún\nframework para permitir adaptadores futuros.\n\n## Clipboard y actualizaciones estables\n\n`pasteMatrix` procesa matrices TSV con validación antes de mutar el modelo. Es atómico\npor defecto y devuelve los cambios y errores para que un adaptador decida cómo persistirlos.\nEl arreglo `columns` define explícitamente el mapeo: un adaptador Angular puede pasar\nsolo columnas visibles o el arreglo completo si desea incluir columnas ocultas.\nEl hook `confirm` puede cancelar la sobrescritura después de validar y antes de mutar:\n\n```ts\nconst result = await grid.pasteMatrix('Cliente nuevo\\t1250', { row: 0, column: 1 });\nif (result.applied) {\n  for (const change of result.changes) {\n    // Persistir change.row/change.column/change.value si corresponde.\n  }\n}\n```\n\nAl usar `getRowId`, la selección y la celda activa se conservan cuando cambian las\nreferencias de las filas, se ordena o se aplican filtros.\n\nLos editores de columna admiten `type: 'textarea'` además de los tipos básicos.\n","readmeFilename":"README.md"}