@flightdev/ui 2.0.0 → 4.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 (120) hide show
  1. package/README.md +285 -70
  2. package/dist/{chunk-XTDK7ME5.js → chunk-S4DTUQII.js} +246 -19
  3. package/dist/chunk-S4DTUQII.js.map +1 -0
  4. package/dist/core/index.d.ts +423 -3
  5. package/dist/core/index.js +23 -2
  6. package/dist/core/index.js.map +1 -0
  7. package/dist/index.d.ts +2 -3
  8. package/dist/index.js +29 -5
  9. package/dist/index.js.map +1 -0
  10. package/package.json +11 -181
  11. package/.turbo/turbo-build.log +0 -81
  12. package/.turbo/turbo-lint.log +0 -40
  13. package/.turbo/turbo-typecheck.log +0 -4
  14. package/TESTING.md +0 -124
  15. package/dist/adapter-MMD-iHNx.d.ts +0 -424
  16. package/dist/adapters/tier-1/angular.d.ts +0 -60
  17. package/dist/adapters/tier-1/angular.js +0 -2
  18. package/dist/adapters/tier-1/index.d.ts +0 -7
  19. package/dist/adapters/tier-1/index.js +0 -7
  20. package/dist/adapters/tier-1/qwik.d.ts +0 -55
  21. package/dist/adapters/tier-1/qwik.js +0 -2
  22. package/dist/adapters/tier-1/react.d.ts +0 -67
  23. package/dist/adapters/tier-1/react.js +0 -2
  24. package/dist/adapters/tier-1/solid.d.ts +0 -45
  25. package/dist/adapters/tier-1/solid.js +0 -2
  26. package/dist/adapters/tier-1/svelte.d.ts +0 -48
  27. package/dist/adapters/tier-1/svelte.js +0 -2
  28. package/dist/adapters/tier-1/vue.d.ts +0 -47
  29. package/dist/adapters/tier-1/vue.js +0 -2
  30. package/dist/adapters/tier-2/index.d.ts +0 -7
  31. package/dist/adapters/tier-2/index.js +0 -7
  32. package/dist/adapters/tier-2/inferno.d.ts +0 -31
  33. package/dist/adapters/tier-2/inferno.js +0 -2
  34. package/dist/adapters/tier-2/lit.d.ts +0 -34
  35. package/dist/adapters/tier-2/lit.js +0 -2
  36. package/dist/adapters/tier-2/marko.d.ts +0 -59
  37. package/dist/adapters/tier-2/marko.js +0 -2
  38. package/dist/adapters/tier-2/mithril.d.ts +0 -31
  39. package/dist/adapters/tier-2/mithril.js +0 -2
  40. package/dist/adapters/tier-2/preact.d.ts +0 -33
  41. package/dist/adapters/tier-2/preact.js +0 -2
  42. package/dist/adapters/tier-2/stencil.d.ts +0 -52
  43. package/dist/adapters/tier-2/stencil.js +0 -2
  44. package/dist/adapters/tier-3/alpine.d.ts +0 -73
  45. package/dist/adapters/tier-3/alpine.js +0 -2
  46. package/dist/adapters/tier-3/hotwire.d.ts +0 -71
  47. package/dist/adapters/tier-3/hotwire.js +0 -2
  48. package/dist/adapters/tier-3/htmx.d.ts +0 -88
  49. package/dist/adapters/tier-3/htmx.js +0 -2
  50. package/dist/adapters/tier-3/index.d.ts +0 -7
  51. package/dist/adapters/tier-3/index.js +0 -7
  52. package/dist/adapters/tier-3/petite-vue.d.ts +0 -56
  53. package/dist/adapters/tier-3/petite-vue.js +0 -2
  54. package/dist/adapters/tier-3/stimulus.d.ts +0 -63
  55. package/dist/adapters/tier-3/stimulus.js +0 -2
  56. package/dist/adapters/tier-3/vanilla.d.ts +0 -63
  57. package/dist/adapters/tier-3/vanilla.js +0 -2
  58. package/dist/chunk-2SNQ6PTM.js +0 -217
  59. package/dist/chunk-3D4XMIZI.js +0 -136
  60. package/dist/chunk-3HU6GSQ4.js +0 -125
  61. package/dist/chunk-4PZDNFL7.js +0 -148
  62. package/dist/chunk-5IBLFTYL.js +0 -114
  63. package/dist/chunk-64JZJ7OK.js +0 -142
  64. package/dist/chunk-7ZJI3QU2.js +0 -132
  65. package/dist/chunk-CE4FJHQJ.js +0 -133
  66. package/dist/chunk-DTCAUBH5.js +0 -87
  67. package/dist/chunk-NTASPOHG.js +0 -106
  68. package/dist/chunk-OI2AMQLG.js +0 -152
  69. package/dist/chunk-Q7HUE44H.js +0 -106
  70. package/dist/chunk-QH3LOWXU.js +0 -155
  71. package/dist/chunk-QIVAK6BH.js +0 -103
  72. package/dist/chunk-V34XPVGK.js +0 -103
  73. package/dist/chunk-VK7ZPMO7.js +0 -221
  74. package/dist/chunk-X6CNUW6T.js +0 -136
  75. package/dist/chunk-YFGSHW5S.js +0 -121
  76. package/dist/chunk-ZAJVSE7J.js +0 -90
  77. package/docs/ADAPTERS.md +0 -946
  78. package/docs/PATTERNS.md +0 -836
  79. package/src/adapters/tier-1/angular.ts +0 -223
  80. package/src/adapters/tier-1/index.ts +0 -12
  81. package/src/adapters/tier-1/qwik.ts +0 -177
  82. package/src/adapters/tier-1/react.ts +0 -330
  83. package/src/adapters/tier-1/solid.ts +0 -222
  84. package/src/adapters/tier-1/svelte.ts +0 -211
  85. package/src/adapters/tier-1/vue.ts +0 -234
  86. package/src/adapters/tier-2/index.ts +0 -12
  87. package/src/adapters/tier-2/inferno.ts +0 -149
  88. package/src/adapters/tier-2/lit.ts +0 -191
  89. package/src/adapters/tier-2/marko.ts +0 -199
  90. package/src/adapters/tier-2/mithril.ts +0 -152
  91. package/src/adapters/tier-2/preact.ts +0 -133
  92. package/src/adapters/tier-2/stencil.ts +0 -214
  93. package/src/adapters/tier-3/alpine.ts +0 -218
  94. package/src/adapters/tier-3/hotwire.ts +0 -254
  95. package/src/adapters/tier-3/htmx.ts +0 -263
  96. package/src/adapters/tier-3/index.ts +0 -12
  97. package/src/adapters/tier-3/petite-vue.ts +0 -163
  98. package/src/adapters/tier-3/stimulus.ts +0 -233
  99. package/src/adapters/tier-3/vanilla.ts +0 -252
  100. package/src/ambient.d.ts +0 -310
  101. package/src/core/adapter.ts +0 -366
  102. package/src/core/index.ts +0 -56
  103. package/src/core/registry.ts +0 -518
  104. package/src/core/types.ts +0 -461
  105. package/src/htmx.ts +0 -134
  106. package/src/index.ts +0 -263
  107. package/test/__mocks__/stencil-core.ts +0 -19
  108. package/test/__mocks__/stencil-hydrate.ts +0 -15
  109. package/test/adapters/tier-1.test.ts +0 -206
  110. package/test/adapters/tier-2.test.ts +0 -175
  111. package/test/adapters/tier-3.test.ts +0 -284
  112. package/test/contracts/adapter.contract.ts +0 -293
  113. package/test/core/core.test.ts +0 -310
  114. package/test/errors/error-handling.test.ts +0 -454
  115. package/test/integration/htmx.integration.test.ts +0 -246
  116. package/test/integration/react.integration.test.ts +0 -271
  117. package/test/integration/registry.integration.test.ts +0 -308
  118. package/tsconfig.json +0 -22
  119. package/tsup.config.ts +0 -93
  120. package/vitest.config.ts +0 -101
@@ -1,310 +0,0 @@
1
- /**
2
- * @flightdev/ui - Core Module Tests
3
- *
4
- * Tests for the core infrastructure: types and base adapter.
5
- */
6
-
7
- import { describe, it, expect, beforeEach, beforeAll } from 'vitest';
8
-
9
- // ============================================================================
10
- // Type Tests
11
- // ============================================================================
12
-
13
- import type { AdapterCapabilities } from '../../src/core/types.js';
14
-
15
- import { DEFAULT_CAPABILITIES, TIER_INFO } from '../../src/core/types.js';
16
-
17
- describe('Core Types', () => {
18
- describe('DEFAULT_CAPABILITIES', () => {
19
- it('has all required capability flags', () => {
20
- expect(DEFAULT_CAPABILITIES).toHaveProperty('streaming');
21
- expect(DEFAULT_CAPABILITIES).toHaveProperty('partialHydration');
22
- expect(DEFAULT_CAPABILITIES).toHaveProperty('islands');
23
- expect(DEFAULT_CAPABILITIES).toHaveProperty('resumable');
24
- expect(DEFAULT_CAPABILITIES).toHaveProperty('ssg');
25
- expect(DEFAULT_CAPABILITIES).toHaveProperty('csr');
26
- expect(DEFAULT_CAPABILITIES).toHaveProperty('serverComponents');
27
- });
28
-
29
- it('all capabilities are booleans', () => {
30
- for (const [key, value] of Object.entries(DEFAULT_CAPABILITIES)) {
31
- expect(typeof value, `${key} should be boolean`).toBe('boolean');
32
- }
33
- });
34
-
35
- it('defaults are conservative (false)', () => {
36
- expect(DEFAULT_CAPABILITIES.streaming).toBe(false);
37
- expect(DEFAULT_CAPABILITIES.serverComponents).toBe(false);
38
- expect(DEFAULT_CAPABILITIES.resumable).toBe(false);
39
- });
40
- });
41
-
42
- describe('TIER_INFO', () => {
43
- it('has info for all three tiers', () => {
44
- expect(TIER_INFO['tier-1']).toBeDefined();
45
- expect(TIER_INFO['tier-2']).toBeDefined();
46
- expect(TIER_INFO['tier-3']).toBeDefined();
47
- });
48
-
49
- it('each tier has name and description', () => {
50
- for (const tier of ['tier-1', 'tier-2', 'tier-3'] as const) {
51
- expect(TIER_INFO[tier].name).toBeDefined();
52
- expect(TIER_INFO[tier].description).toBeDefined();
53
- expect(typeof TIER_INFO[tier].name).toBe('string');
54
- expect(typeof TIER_INFO[tier].description).toBe('string');
55
- }
56
- });
57
- });
58
- });
59
-
60
- // ============================================================================
61
- // Base Adapter Tests
62
- // ============================================================================
63
-
64
- import { BaseUIAdapter, isV2Adapter } from '../../src/core/adapter.js';
65
- import type { Component, RenderResult } from '../../src/core/types.js';
66
-
67
- // Create a testable subclass to access protected methods
68
- class TestableAdapter extends BaseUIAdapter {
69
- readonly id = 'test';
70
- readonly name = 'Test Adapter';
71
- readonly framework = 'test-framework';
72
- readonly tier = 'tier-2' as const;
73
-
74
- // Expose protected methods for testing
75
- public testGenerateId = () => this.generateId();
76
- public testEscapeHtml = (html: string) => this.escapeHtml(html);
77
- public testSerializeProps = (props?: Record<string, unknown>) => this.serializeProps(props);
78
- public testCreateTiming = (startTime: number) => this.createTiming(startTime);
79
-
80
- async renderToString(component: Component): Promise<RenderResult> {
81
- const html = `<div>${(component.props as { text?: string })?.text ?? 'default'}</div>`;
82
- return {
83
- html,
84
- hydrationData: { props: component.props },
85
- timing: this.createTiming(performance.now() - 1),
86
- };
87
- }
88
-
89
- getHydrationScript(): string {
90
- return '<script>/* hydration */</script>';
91
- }
92
-
93
- getClientEntry(): string {
94
- return 'export function hydrate() {}';
95
- }
96
- }
97
-
98
- describe('BaseUIAdapter', () => {
99
- let adapter: TestableAdapter;
100
-
101
- beforeEach(() => {
102
- adapter = new TestableAdapter();
103
- });
104
-
105
- describe('Identity', () => {
106
- it('has required identity properties', () => {
107
- expect(adapter.id).toBe('test');
108
- expect(adapter.name).toBe('Test Adapter');
109
- expect(adapter.framework).toBe('test-framework');
110
- expect(adapter.tier).toBe('tier-2');
111
- });
112
- });
113
-
114
- describe('Capabilities', () => {
115
- it('has default capabilities', () => {
116
- expect(adapter.capabilities).toBeDefined();
117
- expect(adapter.capabilities.streaming).toBe(false);
118
- });
119
- });
120
-
121
- describe('Helper Methods', () => {
122
- it('generateId returns unique IDs', () => {
123
- const id1 = adapter.testGenerateId();
124
- const id2 = adapter.testGenerateId();
125
-
126
- expect(id1).toBeDefined();
127
- expect(id2).toBeDefined();
128
- expect(id1).not.toBe(id2);
129
- });
130
-
131
- it('escapeHtml escapes special characters', () => {
132
- const escaped = adapter.testEscapeHtml('<script>alert("xss")</script>');
133
-
134
- expect(escaped).not.toContain('<script>');
135
- expect(escaped).toContain('&lt;');
136
- expect(escaped).toContain('&gt;');
137
- });
138
-
139
- it('serializeProps returns JSON string', () => {
140
- const serialized = adapter.testSerializeProps({ name: 'test', count: 42 });
141
-
142
- expect(typeof serialized).toBe('string');
143
- expect(JSON.parse(serialized)).toEqual({ name: 'test', count: 42 });
144
- });
145
-
146
- it('serializeProps handles undefined', () => {
147
- const serialized = adapter.testSerializeProps(undefined);
148
-
149
- expect(serialized).toBe('{}');
150
- });
151
-
152
- it('createTiming returns timing object', () => {
153
- const timing = adapter.testCreateTiming(performance.now() - 100);
154
-
155
- expect(timing).toBeDefined();
156
- expect(typeof timing.total).toBe('number');
157
- expect(timing.total).toBeGreaterThanOrEqual(0);
158
- });
159
- });
160
-
161
- describe('Render', () => {
162
- it('renderToString returns RenderResult', async () => {
163
- const result = await adapter.renderToString({
164
- component: () => { },
165
- props: { text: 'Hello' },
166
- });
167
-
168
- expect(result.html).toContain('Hello');
169
- expect(result.hydrationData).toBeDefined();
170
- expect(result.timing).toBeDefined();
171
- });
172
- });
173
-
174
- describe('Islands (Default)', () => {
175
- it('createIsland is defined', () => {
176
- expect(typeof adapter.createIsland).toBe('function');
177
- });
178
-
179
- it('createIsland returns island object', () => {
180
- const island = adapter.createIsland('my-comp', { prop: 'value' });
181
-
182
- expect(island.id).toBeDefined();
183
- expect(island.component).toBe('my-comp');
184
- expect(island.props).toEqual({ prop: 'value' });
185
- expect(island.placeholder).toBeDefined();
186
- });
187
- });
188
- });
189
-
190
- // ============================================================================
191
- // Adapter Utilities Tests
192
- // ============================================================================
193
-
194
- describe('isV2Adapter', () => {
195
- it('returns true for V2 adapters', () => {
196
- const v2Adapter = {
197
- id: 'test',
198
- name: 'Test',
199
- framework: 'test',
200
- tier: 'tier-1',
201
- capabilities: { ...DEFAULT_CAPABILITIES },
202
- renderToString: async () => ({ html: '' }),
203
- getHydrationScript: () => '',
204
- getClientEntry: () => '',
205
- };
206
-
207
- expect(isV2Adapter(v2Adapter)).toBe(true);
208
- });
209
-
210
- it('returns false for V1 adapters', () => {
211
- const v1Adapter = {
212
- name: 'test',
213
- framework: 'test',
214
- renderToString: async () => ({ html: '' }),
215
- getHydrationScript: () => '',
216
- getClientEntry: () => '',
217
- };
218
-
219
- // V1 adapters don't have 'tier' or 'capabilities'
220
- expect(isV2Adapter(v1Adapter)).toBe(false);
221
- });
222
- });
223
-
224
- // ============================================================================
225
- // Registry Tests
226
- // ============================================================================
227
-
228
- import { adapterRegistry, registerBuiltinAdapters } from '../../src/core/registry.js';
229
-
230
- describe('AdapterRegistry', () => {
231
- beforeAll(() => {
232
- registerBuiltinAdapters();
233
- });
234
-
235
- describe('Registration', () => {
236
- it('registerBuiltinAdapters registers all adapters', () => {
237
- // Check Tier 1
238
- expect(adapterRegistry.has('react')).toBe(true);
239
- expect(adapterRegistry.has('vue')).toBe(true);
240
- expect(adapterRegistry.has('angular')).toBe(true);
241
-
242
- // Check Tier 2
243
- expect(adapterRegistry.has('preact')).toBe(true);
244
- expect(adapterRegistry.has('lit')).toBe(true);
245
-
246
- // Check Tier 3
247
- expect(adapterRegistry.has('htmx')).toBe(true);
248
- expect(adapterRegistry.has('alpine')).toBe(true);
249
- });
250
-
251
- it('lists adapters by tier', () => {
252
- const tier1 = adapterRegistry.listByTier('tier-1');
253
- expect(tier1).toContain('react');
254
- expect(tier1).toContain('vue');
255
- expect(tier1).toContain('angular');
256
- expect(tier1).toContain('svelte');
257
- expect(tier1).toContain('solid');
258
- expect(tier1).toContain('qwik');
259
- expect(tier1.length).toBe(6);
260
-
261
- const tier2 = adapterRegistry.listByTier('tier-2');
262
- expect(tier2).toContain('preact');
263
- expect(tier2).toContain('lit');
264
- expect(tier2.length).toBe(6);
265
-
266
- const tier3 = adapterRegistry.listByTier('tier-3');
267
- expect(tier3).toContain('htmx');
268
- expect(tier3).toContain('alpine');
269
- expect(tier3.length).toBe(6);
270
- });
271
-
272
- it('total adapters is 18', () => {
273
- const tier1 = adapterRegistry.listByTier('tier-1');
274
- const tier2 = adapterRegistry.listByTier('tier-2');
275
- const tier3 = adapterRegistry.listByTier('tier-3');
276
-
277
- expect(tier1.length + tier2.length + tier3.length).toBe(18);
278
- });
279
- });
280
-
281
- describe('Retrieval', () => {
282
- it('get returns adapter instance', async () => {
283
- const adapter = await adapterRegistry.get('react');
284
- expect(adapter).toBeDefined();
285
- expect(adapter?.id).toBe('react');
286
- });
287
-
288
- it('get returns undefined for unknown adapter', async () => {
289
- const adapter = await adapterRegistry.get('unknown-adapter');
290
- expect(adapter).toBeUndefined();
291
- });
292
- });
293
-
294
- describe('Query', () => {
295
- it('listByCapability returns adapters with capability', () => {
296
- const streaming = adapterRegistry.listByCapability('streaming');
297
- expect(streaming).toContain('react');
298
- expect(streaming).toContain('vue');
299
- expect(streaming).toContain('solid');
300
- expect(streaming).toContain('qwik');
301
- expect(streaming).toContain('marko');
302
- });
303
-
304
- it('listByCapability filters correctly', () => {
305
- const resumable = adapterRegistry.listByCapability('resumable');
306
- expect(resumable).toContain('qwik');
307
- expect(resumable).not.toContain('react');
308
- });
309
- });
310
- });