letopis 1.4.2 → 3.0.0

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 (123) hide show
  1. package/AGENT-CHEATSHEET.md +516 -398
  2. package/CHANGELOG.md +739 -0
  3. package/LICENSE +75 -21
  4. package/LICENSE-COMMERCIAL.md +49 -0
  5. package/README.md +1312 -1190
  6. package/api-contract.json +381 -0
  7. package/dist/acl.d.ts +81 -1
  8. package/dist/acl.js +281 -13
  9. package/dist/admin.d.ts +11 -141
  10. package/dist/admin.js +28 -186
  11. package/dist/auth.d.ts +20 -5
  12. package/dist/auth.js +80 -21
  13. package/dist/cache.d.ts +8 -1
  14. package/dist/cache.js +30 -8
  15. package/dist/chain.d.ts +46 -48
  16. package/dist/chain.js +556 -223
  17. package/dist/cli.js +73 -96
  18. package/dist/demo/booking.d.ts +352 -36
  19. package/dist/describe.d.ts +47 -0
  20. package/dist/describe.js +195 -0
  21. package/dist/errors.d.ts +77 -13
  22. package/dist/errors.js +231 -30
  23. package/dist/index.d.ts +62 -74
  24. package/dist/index.js +312 -155
  25. package/dist/internal.d.ts +7 -0
  26. package/dist/jsonschema.js +18 -17
  27. package/dist/load.d.ts +29 -17
  28. package/dist/load.js +235 -190
  29. package/dist/log.d.ts +121 -0
  30. package/dist/log.js +633 -0
  31. package/dist/mcp.d.ts +5 -7
  32. package/dist/mcp.js +194 -225
  33. package/dist/messages/access.d.ts +90 -0
  34. package/dist/messages/access.js +113 -0
  35. package/dist/messages/api.d.ts +237 -0
  36. package/dist/messages/api.js +304 -0
  37. package/dist/messages/boot.d.ts +201 -0
  38. package/dist/messages/boot.js +256 -0
  39. package/dist/messages/codes.d.ts +172 -0
  40. package/dist/messages/codes.js +173 -0
  41. package/dist/messages/index.d.ts +98 -0
  42. package/dist/messages/index.js +121 -0
  43. package/dist/messages/log.d.ts +229 -0
  44. package/dist/messages/log.js +102 -0
  45. package/dist/messages/mcp.d.ts +306 -0
  46. package/dist/messages/mcp.js +387 -0
  47. package/dist/messages/model.d.ts +256 -0
  48. package/dist/messages/model.js +314 -0
  49. package/dist/messages/query.d.ts +141 -0
  50. package/dist/messages/query.js +171 -0
  51. package/dist/messages/sql-access.d.ts +70 -0
  52. package/dist/messages/sql-access.js +87 -0
  53. package/dist/messages/sql-core.d.ts +164 -0
  54. package/dist/messages/sql-core.js +198 -0
  55. package/dist/messages/sql-time.d.ts +86 -0
  56. package/dist/messages/sql-time.js +111 -0
  57. package/dist/messages/sql-write.d.ts +246 -0
  58. package/dist/messages/sql-write.js +270 -0
  59. package/dist/messages/time.d.ts +23 -0
  60. package/dist/messages/time.js +29 -0
  61. package/dist/messages/types.d.ts +27 -0
  62. package/dist/messages/types.js +5 -0
  63. package/dist/messages/write.d.ts +452 -0
  64. package/dist/messages/write.js +572 -0
  65. package/dist/model.d.ts +77 -60
  66. package/dist/model.js +43 -34
  67. package/dist/ops.d.ts +35 -0
  68. package/dist/ops.js +101 -0
  69. package/dist/pglite.d.ts +0 -9
  70. package/dist/pglite.js +3 -1
  71. package/dist/registry.d.ts +3 -19
  72. package/dist/registry.js +3 -16
  73. package/dist/signals.d.ts +1 -5
  74. package/dist/signals.js +1 -5
  75. package/dist/sql.d.ts +9 -1
  76. package/dist/sql.js +175 -107
  77. package/dist/sync.d.ts +10 -4
  78. package/dist/sync.js +90 -17
  79. package/dist/tx.d.ts +21 -2
  80. package/dist/tx.js +76 -13
  81. package/dist/typed.d.ts +252 -53
  82. package/dist/types.d.ts +93 -90
  83. package/dist/types.js +17 -14
  84. package/dist/up.d.ts +56 -35
  85. package/dist/up.js +229 -83
  86. package/dist/uuid.d.ts +8 -0
  87. package/dist/uuid.js +14 -6
  88. package/dist/validate.d.ts +13 -1
  89. package/dist/validate.js +82 -33
  90. package/dist/watch.d.ts +10 -16
  91. package/dist/watch.js +36 -77
  92. package/dist/write.d.ts +87 -17
  93. package/dist/write.js +441 -206
  94. package/llms.txt +48 -31
  95. package/package.json +13 -14
  96. package/sql/10-core.sql +7 -50
  97. package/sql/15-errors.sql +64 -10
  98. package/sql/20-context.sql +18 -9
  99. package/sql/30-validate.sql +79 -30
  100. package/sql/40-class.sql +41 -115
  101. package/sql/50-acl.sql +8 -13
  102. package/sql/60-write.sql +220 -676
  103. package/sql/70-read.sql +11 -13
  104. package/sql/80-auth.sql +109 -42
  105. package/sql/90-time.sql +108 -947
  106. package/sql/95-seed.system.sql +7 -14
  107. package/sql/99-revision.sql +6 -1
  108. package/sql/README.md +32 -24
  109. package/sql/migrate/0009-restore-rev.tenants-name.sql +10 -0
  110. package/sql/migrate/0010-impersonation-no-account.sql +5 -0
  111. package/sql/migrate/0011-key-lock.otp-enabled.sql +7 -0
  112. package/sql/migrate/README.md +18 -0
  113. package/AGENT-CHEATSHEET.en.md +0 -488
  114. package/MIGRATION.md +0 -190
  115. package/README.en.md +0 -2910
  116. package/dist/import.d.ts +0 -185
  117. package/dist/import.js +0 -820
  118. package/dist/project.d.ts +0 -359
  119. package/dist/project.js +0 -1258
  120. package/sql/75-history.sql +0 -436
  121. package/sql/88-derived.sql +0 -1236
  122. package/sql/migrate/0006-changed-paths.sql +0 -3
  123. package/sql/migrate/0007-secret-account-fk.sql +0 -12
package/dist/registry.js CHANGED
@@ -3,19 +3,8 @@
3
3
  * (собственные классы арендатора и системные), поиск по имени и алиасу, предки и потомки,
4
4
  * типы листьев для фильтров и валидатор на TypeScript, скомпилированный из того же описания.
5
5
  */
6
- import { LetopisError } from './errors.js';
6
+ import { lerr } from './errors.js';
7
7
  import { compileValidator } from './validate.js';
8
- /** Агрегатные поля класса: их считает база (план 1.1, §2.4). */
9
- export const aggregateFields = (cls) => Object.keys(cls.aggregate ?? {});
10
- /** Описание агрегатов из resolved — без скомпилированного условия (match): оно для базы. */
11
- function aggregateOf(agg) {
12
- return Object.fromEntries(Object.entries(agg).map(([field, d]) => [field, {
13
- ...(typeof d.sum === 'string' ? { sum: d.sum } : { count: true }),
14
- of: d.of,
15
- via: d.via,
16
- ...(d.where && typeof d.where === 'object' ? { where: d.where } : {}),
17
- }]));
18
- }
19
8
  export class Registry {
20
9
  byName = new Map();
21
10
  byAlias = new Map();
@@ -37,12 +26,10 @@ export class Registry {
37
26
  schema: res.schema,
38
27
  ends: (res.ends ?? {}),
39
28
  key: (res.key ?? []),
40
- history: res.history,
29
+ history: res.history !== false,
41
30
  ownerDefault: (res.ownerDefault ?? 'tenant'),
42
31
  cache: (res.cache ?? undefined),
43
32
  meta: (res.meta ?? {}),
44
- ...(typeof res.derivedBy === 'string' ? { derivedBy: res.derivedBy } : {}),
45
- ...(res.aggregate && typeof res.aggregate === 'object' ? { aggregate: aggregateOf(res.aggregate) } : {}),
46
33
  validator: () => (compiled ??= compileValidator(res.schema)),
47
34
  };
48
35
  this.byName.set(info.name, info);
@@ -59,7 +46,7 @@ export class Registry {
59
46
  resolve(name) {
60
47
  const c = this.find(name);
61
48
  if (!c)
62
- throw new LetopisError('invalid_class', `класс ${name} не найден`);
49
+ throw lerr('model.class_not_found', { name });
63
50
  return c;
64
51
  }
65
52
  all() {
package/dist/signals.d.ts CHANGED
@@ -2,14 +2,10 @@ export type SignalMode = 'class' | 'tenant' | 'opaque' | 'none';
2
2
  export declare const SIGNAL_MODES: readonly SignalMode[];
3
3
  /** Разобранный сигнал. */
4
4
  export type Signal =
5
- /** `*` — сброс: кэш, пропуска прав, реестр и ключ — заново. */
5
+ /** Слушатель сигналов (пере)подключился — сигналы за время обрыва потеряны: кэш, пропуска прав, реестр и ключ — заново. */
6
6
  {
7
7
  kind: 'all';
8
8
  }
9
- /** `session:*` — все сессии. */
10
- | {
11
- kind: 'sessions';
12
- }
13
9
  /** `session:<тег>` — погашенная сессия (тег — начало sha256 токена). */
14
10
  | {
15
11
  kind: 'session';
package/dist/signals.js CHANGED
@@ -4,7 +4,7 @@
4
4
  * Канал — имя схемы; нагрузку строит функция базы signal() по режиму up({ signals }):
5
5
  * - class — `Booking` (как в 1.0); tenant — `Booking@<токен арендатора>`;
6
6
  * - opaque — `<токен класса>@<токен арендатора>`; none — сигналов нет;
7
- * - сессии — `session:<16 hex>` и `session:*`, сброс — `*` (кроме none).
7
+ * - погашенная сессия — `session:<16 hex>` (кроме none).
8
8
  * Токен — первые 96 бит HMAC-SHA256 от «назначение:значение» на ключе сигналов (signal_key(): HMAC
9
9
  * ключа строки KEY по 'letopis:signals'), 24 строчных шестнадцатеричных знака. Имя класса не содержит
10
10
  * `@`, `:` и `*` (метасхема Class), поэтому нагрузка разбирается однозначно.
@@ -77,10 +77,6 @@ export class Signals {
77
77
  }
78
78
  /** Разобрать нагрузку сигнала или элемент letopis.changed своей транзакции. */
79
79
  parse(p) {
80
- if (p === '*')
81
- return { kind: 'all' };
82
- if (p === 'session:*')
83
- return { kind: 'sessions' };
84
80
  if (p.startsWith('session:'))
85
81
  return /^session:[0-9a-f]{16}$/.test(p) ? { kind: 'session', tag: p.slice(8) } : { kind: 'foreign' };
86
82
  const at = p.indexOf('@');
package/dist/sql.d.ts CHANGED
@@ -18,6 +18,8 @@ export interface Step {
18
18
  tagsFilter?: unknown;
19
19
  ownerFilter?: string;
20
20
  deepMax?: number;
21
+ /** withDeleted(): узел шага — живые и надгробия удалённых (модификатор шага, план 2.1, A9). */
22
+ withDeleted?: true;
21
23
  /** Звено плана записи (этап 4): глагол на этом шаге; построитель чтения его не видит. */
22
24
  op?: import('./write.js').PlanOp;
23
25
  /** Модификаторы цепочки на момент глагола: limit и sort сужают цели записи. */
@@ -29,7 +31,7 @@ export interface Step {
29
31
  }
30
32
  /** Уникальная метка узла пути. */
31
33
  export declare const nextNodeKey: () => number;
32
- export type ReadMode = 'paths' | 'rows' | 'ids' | 'count' | 'countPaths' | 'versions' | 'agg' | 'diff' | 'blame';
34
+ export type ReadMode = 'paths' | 'rows' | 'ids' | 'count' | 'countPaths' | 'versions' | 'agg';
33
35
  export interface AggSpec {
34
36
  fn: 'sum' | 'avg' | 'min' | 'max' | 'countBy';
35
37
  field: string;
@@ -48,6 +50,12 @@ export declare function roleOwners(reg: Registry, role: string): ClassInfo[];
48
50
  export declare function roleTargets(reg: Registry, role: string): string[];
49
51
  /** Конкретные классы, которые матчит шаг: класс (роль — её цели) и потомки, если не exact(). */
50
52
  export declare function stepClasses(reg: Registry, step: Step): string[];
53
+ /**
54
+ * Отказы построителя, которым не нужны база и путь, — фильтр шага (в том числе неизвестное поле) и поле sort('data.…') или
55
+ * агрегата по классам шага: план записи проверяет их до первого оператора (write.ts:precheckPlan, §2.5), поэтому
56
+ * опечатка в фильтре цели не ломает db.begin(). Построитель при чтении проверяет то же самое ещё раз.
57
+ */
58
+ export declare function precheckStep(reg: Registry, step: Step, order?: string, agg?: AggSpec): void;
51
59
  /** Принимает ли список классов конца класс cls (с учётом его предков). */
52
60
  export declare const accepts: (reg: Registry, targets: string[], cls: string) => boolean;
53
61
  export interface Hop {