@artkit-ai/core 0.1.0 → 0.2.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 (87) hide show
  1. package/dist/adapter.d.ts +119 -0
  2. package/dist/adapter.d.ts.map +1 -0
  3. package/dist/adapter.js +45 -0
  4. package/dist/adapter.js.map +1 -0
  5. package/dist/diff.d.ts +1 -1
  6. package/dist/diff.d.ts.map +1 -1
  7. package/dist/engine.d.ts +29 -23
  8. package/dist/engine.d.ts.map +1 -1
  9. package/dist/engine.js +148 -197
  10. package/dist/engine.js.map +1 -1
  11. package/dist/envelope.d.ts +10 -27
  12. package/dist/envelope.d.ts.map +1 -1
  13. package/dist/envelope.js +8 -20
  14. package/dist/envelope.js.map +1 -1
  15. package/dist/errors.d.ts +1 -1
  16. package/dist/errors.d.ts.map +1 -1
  17. package/dist/errors.js +4 -4
  18. package/dist/errors.js.map +1 -1
  19. package/dist/events.d.ts +2 -10
  20. package/dist/events.d.ts.map +1 -1
  21. package/dist/events.js.map +1 -1
  22. package/dist/i18n.d.ts +8 -14
  23. package/dist/i18n.d.ts.map +1 -1
  24. package/dist/i18n.js +12 -18
  25. package/dist/i18n.js.map +1 -1
  26. package/dist/index.d.ts +2 -2
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +2 -2
  29. package/dist/index.js.map +1 -1
  30. package/dist/logger.d.ts +1 -2
  31. package/dist/logger.d.ts.map +1 -1
  32. package/dist/logger.js.map +1 -1
  33. package/dist/memory.d.ts +0 -2
  34. package/dist/memory.d.ts.map +1 -1
  35. package/dist/memory.js +15 -109
  36. package/dist/memory.js.map +1 -1
  37. package/dist/migrations.d.ts +6 -5
  38. package/dist/migrations.d.ts.map +1 -1
  39. package/dist/migrations.js +20 -14
  40. package/dist/migrations.js.map +1 -1
  41. package/dist/projection.d.ts +22 -6
  42. package/dist/projection.d.ts.map +1 -1
  43. package/dist/projection.js +5 -5
  44. package/dist/projection.js.map +1 -1
  45. package/dist/registry.d.ts +17 -16
  46. package/dist/registry.d.ts.map +1 -1
  47. package/dist/registry.js +25 -25
  48. package/dist/registry.js.map +1 -1
  49. package/dist/service.d.ts +19 -51
  50. package/dist/service.d.ts.map +1 -1
  51. package/dist/service.js +119 -404
  52. package/dist/service.js.map +1 -1
  53. package/dist/store.d.ts +12 -61
  54. package/dist/store.d.ts.map +1 -1
  55. package/dist/testing/index.d.ts +10 -9
  56. package/dist/testing/index.d.ts.map +1 -1
  57. package/dist/testing/index.js +75 -136
  58. package/dist/testing/index.js.map +1 -1
  59. package/dist/theme.js +1 -1
  60. package/dist/ui.d.ts +18 -1
  61. package/dist/ui.d.ts.map +1 -1
  62. package/dist/ui.js +5 -3
  63. package/dist/ui.js.map +1 -1
  64. package/package.json +1 -1
  65. package/src/adapter.ts +180 -0
  66. package/src/diff.ts +1 -1
  67. package/src/engine.ts +183 -230
  68. package/src/envelope.ts +11 -29
  69. package/src/errors.ts +4 -4
  70. package/src/events.ts +2 -11
  71. package/src/i18n.ts +14 -20
  72. package/src/index.ts +2 -4
  73. package/src/logger.ts +1 -2
  74. package/src/memory.ts +16 -122
  75. package/src/migrations.ts +24 -18
  76. package/src/projection.ts +25 -7
  77. package/src/registry.ts +45 -41
  78. package/src/service.ts +144 -540
  79. package/src/store.ts +12 -64
  80. package/src/testing/index.ts +89 -164
  81. package/src/theme.ts +1 -1
  82. package/src/ui.ts +24 -4
  83. package/dist/kind.d.ts +0 -156
  84. package/dist/kind.d.ts.map +0 -1
  85. package/dist/kind.js +0 -52
  86. package/dist/kind.js.map +0 -1
  87. package/src/kind.ts +0 -217
package/src/registry.ts CHANGED
@@ -1,7 +1,7 @@
1
+ import { type AnyFormatAdapter, assertFormatContract, type FormatLimits } from './adapter.js';
1
2
  import type { AssetResolver } from './assets.js';
2
3
  import { ArtifactError } from './errors.js';
3
4
  import { t } from './i18n.js';
4
- import { type AnyArtifactKind, assertKindContract, type KindLimits } from './kind.js';
5
5
  import type { Logger } from './logger.js';
6
6
  import { defaultTheme, type Theme, themeSchema } from './theme.js';
7
7
 
@@ -26,48 +26,49 @@ export interface ExportContext {
26
26
  assets: AssetResolver;
27
27
  logger: Logger;
28
28
  signal?: AbortSignal;
29
- /** Records a fidelity degradation (spec §12.4), returned to the caller as `warnings`. */
29
+ /** Records a fidelity degradation (spec §13), returned to the caller as `warnings`. */
30
30
  warn(message: string): void;
31
31
  /** Exporter-specific options (e.g. `sheet` for per-sheet CSV). */
32
32
  options?: Record<string, unknown>;
33
33
  }
34
34
 
35
+ /** Exporters live beside the adapter (spec §8): `format` is the native source, `target` the file format. */
35
36
  export interface ArtifactExporter<Content = unknown> {
36
- kind: string;
37
- format: ExportFormat;
37
+ format: string;
38
+ target: ExportFormat;
38
39
  mimeType: string;
39
40
  extension: string;
40
41
  runtime: 'any' | 'node' | 'browser';
41
42
  export(content: Content, ctx: ExportContext): Promise<Uint8Array>;
42
43
  }
43
44
 
44
- // biome-ignore lint/suspicious/noExplicitAny: registry stores heterogeneous exporters.
45
+ // biome-ignore lint/suspicious/noExplicitAny: the registry stores heterogeneous exporters.
45
46
  export type AnyArtifactExporter = ArtifactExporter<any>;
46
47
 
47
48
  export interface BatchLimits {
48
- /** Operations per batch (spec §6.6: 200). */
49
+ /** Operations per batch (spec §7.5: 200). */
49
50
  maxOperations: number;
50
- /** Serialized envelope size in bytes (spec §6.6: 5 MB). */
51
+ /** Serialized envelope size in bytes (spec §7.5: 5 MB). */
51
52
  maxEnvelopeBytes: number;
52
53
  }
53
54
 
54
55
  export const DEFAULT_BATCH_LIMITS: BatchLimits = { maxOperations: 200, maxEnvelopeBytes: 5 * 1024 * 1024 };
55
56
 
56
57
  export interface RegistryOptions {
57
- kinds?: AnyArtifactKind[];
58
+ formats?: AnyFormatAdapter[];
58
59
  themes?: Theme[];
59
60
  exporters?: AnyArtifactExporter[];
60
- /** Per-kind overrides of the default limits. */
61
- limits?: Record<string, Partial<KindLimits>>;
61
+ /** Per-format overrides of the default limits. */
62
+ limits?: Record<string, Partial<FormatLimits>>;
62
63
  batch?: Partial<BatchLimits>;
63
64
  }
64
65
 
65
66
  export interface ArtifactRegistry {
66
- register(kind: AnyArtifactKind): void;
67
- get(kind: string, locale?: string): AnyArtifactKind;
68
- has(kind: string): boolean;
69
- kinds(): AnyArtifactKind[];
70
- limits(kind: string): KindLimits;
67
+ register(adapter: AnyFormatAdapter): void;
68
+ get(format: string, locale?: string): AnyFormatAdapter;
69
+ has(format: string): boolean;
70
+ formats(): AnyFormatAdapter[];
71
+ limits(format: string): FormatLimits;
71
72
  readonly batch: BatchLimits;
72
73
 
73
74
  registerTheme(theme: Theme): void;
@@ -76,12 +77,12 @@ export interface ArtifactRegistry {
76
77
  themes(): Theme[];
77
78
 
78
79
  registerExporter(exporter: AnyArtifactExporter, options?: { replace?: boolean }): void;
79
- exporter(kind: string, format: string, locale?: string): AnyArtifactExporter;
80
- exporters(kind?: string): AnyArtifactExporter[];
80
+ exporter(format: string, target: string, locale?: string): AnyArtifactExporter;
81
+ exporters(format?: string): AnyArtifactExporter[];
81
82
  }
82
83
 
83
84
  export function createRegistry(options: RegistryOptions = {}): ArtifactRegistry {
84
- const kinds = new Map<string, AnyArtifactKind>();
85
+ const formats = new Map<string, AnyFormatAdapter>();
85
86
  const themes = new Map<string, Theme>([[defaultTheme.id, defaultTheme]]);
86
87
  const exporters = new Map<string, AnyArtifactExporter>();
87
88
  const limitOverrides = options.limits ?? {};
@@ -89,35 +90,38 @@ export function createRegistry(options: RegistryOptions = {}): ArtifactRegistry
89
90
 
90
91
  const registry: ArtifactRegistry = {
91
92
  batch,
92
- register(kind) {
93
- if (kinds.has(kind.kind)) {
94
- throw new ArtifactError('DUPLICATE_KIND', t(undefined, 'DUPLICATE_KIND', { kind: kind.kind }));
93
+ register(adapter) {
94
+ if (formats.has(adapter.format)) {
95
+ throw new ArtifactError(
96
+ 'DUPLICATE_FORMAT',
97
+ t(undefined, 'DUPLICATE_FORMAT', { format: adapter.format }),
98
+ );
95
99
  }
96
- assertKindContract(kind);
97
- kinds.set(kind.kind, kind);
100
+ assertFormatContract(adapter);
101
+ formats.set(adapter.format, adapter);
98
102
  },
99
- get(kind, locale) {
100
- const found = kinds.get(kind);
103
+ get(format, locale) {
104
+ const found = formats.get(format);
101
105
  if (!found) {
102
- throw new ArtifactError('UNKNOWN_KIND', t(locale, 'UNKNOWN_KIND', { kind }), {
106
+ throw new ArtifactError('UNKNOWN_FORMAT', t(locale, 'UNKNOWN_FORMAT', { format }), {
103
107
  issues: [
104
108
  {
105
- path: 'kind',
106
- message: t(locale, 'UNKNOWN_KIND', { kind }),
107
- hint: t(locale, 'UNKNOWN_KIND_HINT', { available: [...kinds.keys()].join(', ') }),
109
+ path: 'format',
110
+ message: t(locale, 'UNKNOWN_FORMAT', { format }),
111
+ hint: t(locale, 'UNKNOWN_FORMAT_HINT', { available: [...formats.keys()].join(', ') }),
108
112
  },
109
113
  ],
110
114
  });
111
115
  }
112
116
  return found;
113
117
  },
114
- has: (kind) => kinds.has(kind),
115
- kinds: () => [...kinds.values()],
116
- limits(kind) {
117
- const base = registry.get(kind).limits;
118
+ has: (format) => formats.has(format),
119
+ formats: () => [...formats.values()],
120
+ limits(format) {
121
+ const base = registry.get(format).limits;
118
122
  const overrides = Object.fromEntries(
119
- Object.entries(limitOverrides[kind] ?? {}).filter(([, v]) => v !== undefined),
120
- ) as KindLimits;
123
+ Object.entries(limitOverrides[format] ?? {}).filter(([, v]) => v !== undefined),
124
+ ) as FormatLimits;
121
125
  return { ...base, ...overrides };
122
126
  },
123
127
  registerTheme(theme) {
@@ -131,21 +135,21 @@ export function createRegistry(options: RegistryOptions = {}): ArtifactRegistry
131
135
  hasTheme: (id) => themes.has(id),
132
136
  themes: () => [...themes.values()],
133
137
  registerExporter(exporter, opts) {
134
- const key = `${exporter.kind}:${exporter.format}`;
138
+ const key = `${exporter.format}:${exporter.target}`;
135
139
  if (exporters.has(key) && !opts?.replace) {
136
140
  throw new Error(`Exporter ${key} is already registered; pass { replace: true } to override it.`);
137
141
  }
138
142
  exporters.set(key, exporter);
139
143
  },
140
- exporter(kind, format, locale) {
141
- const found = exporters.get(`${kind}:${format}`);
142
- if (!found) throw new ArtifactError('NOT_FOUND', t(locale, 'EXPORTER_NOT_FOUND', { kind, format }));
144
+ exporter(format, target, locale) {
145
+ const found = exporters.get(`${format}:${target}`);
146
+ if (!found) throw new ArtifactError('NOT_FOUND', t(locale, 'EXPORTER_NOT_FOUND', { format, target }));
143
147
  return found;
144
148
  },
145
- exporters: (kind) => [...exporters.values()].filter((e) => kind === undefined || e.kind === kind),
149
+ exporters: (format) => [...exporters.values()].filter((e) => format === undefined || e.format === format),
146
150
  };
147
151
 
148
- for (const kind of options.kinds ?? []) registry.register(kind);
152
+ for (const adapter of options.formats ?? []) registry.register(adapter);
149
153
  for (const theme of options.themes ?? []) registry.registerTheme(theme);
150
154
  for (const exporter of options.exporters ?? []) registry.registerExporter(exporter, { replace: true });
151
155
  return registry;