@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,271 +0,0 @@
1
- /**
2
- * @flightdev/ui - React Integration Tests
3
- *
4
- * Tests for React adapter with real rendering scenarios.
5
- * Validates SSR output, hydration scripts, and streaming behavior.
6
- *
7
- * @module test/integration/react.integration.test.ts
8
- */
9
-
10
- import { describe, it, expect, beforeEach, vi } from 'vitest';
11
- import { adapterRegistry, registerBuiltinAdapters } from '../../src/core/registry.js';
12
- import type { Component, RenderResult, RenderContext } from '../../src/core/types.js';
13
-
14
- // ============================================================================
15
- // React Integration Tests
16
- // ============================================================================
17
-
18
- describe('React Integration Tests', () => {
19
- beforeEach(() => {
20
- registerBuiltinAdapters();
21
- });
22
-
23
- describe('Adapter Retrieval', () => {
24
- it('should load React adapter from registry', async () => {
25
- const adapter = await adapterRegistry.get('react');
26
-
27
- expect(adapter).toBeDefined();
28
- expect(adapter?.id).toBe('react');
29
- expect(adapter?.name).toBe('React');
30
- expect(adapter?.tier).toBe('tier-1');
31
- });
32
-
33
- it('should have correct React capabilities', async () => {
34
- const adapter = await adapterRegistry.get('react');
35
-
36
- expect(adapter?.capabilities.streaming).toBe(true);
37
- expect(adapter?.capabilities.partialHydration).toBe(true);
38
- expect(adapter?.capabilities.islands).toBe(true);
39
- expect(adapter?.capabilities.serverComponents).toBe(true);
40
- expect(adapter?.capabilities.ssg).toBe(true);
41
- expect(adapter?.capabilities.csr).toBe(true);
42
- });
43
- });
44
-
45
- describe('SSR Rendering', () => {
46
- it('should render component to HTML string', async () => {
47
- const adapter = await adapterRegistry.get('react');
48
- expect(adapter).toBeDefined();
49
-
50
- // Component that returns null is the simplest valid React component
51
- const component: Component = {
52
- component: function SimpleComponent() {
53
- return null;
54
- },
55
- props: {},
56
- };
57
-
58
- const result = await adapter!.renderToString(component);
59
-
60
- expect(result).toBeDefined();
61
- expect(typeof result.html).toBe('string');
62
- expect(result.timing).toBeDefined();
63
- expect(result.timing?.total).toBeGreaterThanOrEqual(0);
64
- });
65
-
66
- it('should pass props to component during render', async () => {
67
- const adapter = await adapterRegistry.get('react');
68
- expect(adapter).toBeDefined();
69
-
70
- const mockRenderFn = vi.fn();
71
- const component: Component = {
72
- component: mockRenderFn,
73
- props: { name: 'World', count: 42 },
74
- };
75
-
76
- // The render should attempt to call the component with props
77
- try {
78
- await adapter!.renderToString(component);
79
- } catch {
80
- // Expected - mock component won't render properly
81
- }
82
-
83
- // Component should have been created with props accessible
84
- expect(component.props).toEqual({ name: 'World', count: 42 });
85
- });
86
-
87
- it('should include timing information in render result', async () => {
88
- const adapter = await adapterRegistry.get('react');
89
- expect(adapter).toBeDefined();
90
-
91
- const component: Component = {
92
- component: () => null,
93
- props: {},
94
- };
95
-
96
- try {
97
- const result = await adapter!.renderToString(component);
98
- expect(result.timing).toBeDefined();
99
- expect(typeof result.timing?.total).toBe('number');
100
- } catch {
101
- // May throw due to mock component - that's ok for this test
102
- }
103
- });
104
- });
105
-
106
- describe('Hydration Scripts', () => {
107
- it('should generate hydration script with proper structure', async () => {
108
- const adapter = await adapterRegistry.get('react');
109
- expect(adapter).toBeDefined();
110
-
111
- const mockResult: RenderResult = {
112
- html: '<div>Test</div>',
113
- hydrationData: { props: { name: 'Test' } },
114
- timing: { total: 5 },
115
- };
116
-
117
- const script = adapter!.getHydrationScript(mockResult);
118
-
119
- expect(typeof script).toBe('string');
120
- expect(script).toContain('<script');
121
- expect(script).toContain('</script>');
122
- });
123
-
124
- it('should include hydration data in script when provided', async () => {
125
- const adapter = await adapterRegistry.get('react');
126
- expect(adapter).toBeDefined();
127
-
128
- const mockResult: RenderResult = {
129
- html: '<div>Test</div>',
130
- hydrationData: { componentId: 'test-123' },
131
- };
132
-
133
- const script = adapter!.getHydrationScript(mockResult);
134
-
135
- // Script should contain some reference to hydration data
136
- expect(script.length).toBeGreaterThan(0);
137
- });
138
- });
139
-
140
- describe('Client Entry', () => {
141
- it('should generate valid client entry code', async () => {
142
- const adapter = await adapterRegistry.get('react');
143
- expect(adapter).toBeDefined();
144
-
145
- const entry = adapter!.getClientEntry();
146
-
147
- expect(typeof entry).toBe('string');
148
- expect(entry.length).toBeGreaterThan(0);
149
- // Should contain React-specific hydration code
150
- expect(entry).toMatch(/hydrat|react|mount/i);
151
- });
152
-
153
- it('should export a hydrate function', async () => {
154
- const adapter = await adapterRegistry.get('react');
155
- expect(adapter).toBeDefined();
156
-
157
- const entry = adapter!.getClientEntry();
158
-
159
- // Client entry should contain export for hydration
160
- expect(entry).toMatch(/export|hydrat/i);
161
- });
162
- });
163
-
164
- describe('Streaming SSR', () => {
165
- it('should have streaming capability enabled', async () => {
166
- const adapter = await adapterRegistry.get('react');
167
- expect(adapter).toBeDefined();
168
-
169
- expect(adapter!.capabilities.streaming).toBe(true);
170
- });
171
-
172
- it('should provide renderToStream method', async () => {
173
- const adapter = await adapterRegistry.get('react');
174
- expect(adapter).toBeDefined();
175
-
176
- expect(typeof adapter!.renderToStream).toBe('function');
177
- });
178
-
179
- it('should return StreamingRenderResult from renderToStream', async () => {
180
- const adapter = await adapterRegistry.get('react');
181
- expect(adapter).toBeDefined();
182
-
183
- const component: Component = {
184
- component: () => null,
185
- props: {},
186
- };
187
-
188
- const result = adapter!.renderToStream!(component);
189
-
190
- expect(result).toBeDefined();
191
- expect(result.stream).toBeDefined();
192
- expect(result.stream instanceof ReadableStream).toBe(true);
193
- // StreamingRenderResult has stream, done, and abort
194
- expect(result.done).toBeDefined();
195
- expect(typeof result.abort).toBe('function');
196
- });
197
- });
198
-
199
- describe('Islands Architecture', () => {
200
- it('should support islands capability', async () => {
201
- const adapter = await adapterRegistry.get('react');
202
- expect(adapter).toBeDefined();
203
-
204
- expect(adapter!.capabilities.islands).toBe(true);
205
- });
206
-
207
- it('should create island with proper structure', async () => {
208
- const adapter = await adapterRegistry.get('react');
209
- expect(adapter).toBeDefined();
210
- expect(adapter!.createIsland).toBeDefined();
211
-
212
- const island = adapter!.createIsland!('UserProfile', { userId: '123' });
213
-
214
- expect(island).toBeDefined();
215
- expect(island.id).toBeDefined();
216
- expect(island.component).toBe('UserProfile');
217
- expect(island.props).toEqual({ userId: '123' });
218
- expect(island.placeholder).toBeDefined();
219
- });
220
-
221
- it('should generate unique island IDs', async () => {
222
- const adapter = await adapterRegistry.get('react');
223
- expect(adapter).toBeDefined();
224
-
225
- const island1 = adapter!.createIsland!('Component1', {});
226
- const island2 = adapter!.createIsland!('Component2', {});
227
-
228
- expect(island1.id).not.toBe(island2.id);
229
- });
230
- });
231
- });
232
-
233
- // ============================================================================
234
- // Error Handling Tests
235
- // ============================================================================
236
-
237
- describe('React Error Handling', () => {
238
- beforeEach(() => {
239
- registerBuiltinAdapters();
240
- });
241
-
242
- it('should handle undefined component gracefully', async () => {
243
- const adapter = await adapterRegistry.get('react');
244
- expect(adapter).toBeDefined();
245
-
246
- const component: Component = {
247
- component: undefined as unknown as () => void,
248
- props: {},
249
- };
250
-
251
- // Should throw or handle gracefully
252
- await expect(adapter!.renderToString(component)).rejects.toThrow();
253
- });
254
-
255
- it('should handle null props gracefully', async () => {
256
- const adapter = await adapterRegistry.get('react');
257
- expect(adapter).toBeDefined();
258
-
259
- const component: Component = {
260
- component: () => null,
261
- props: null as unknown as Record<string, unknown>,
262
- };
263
-
264
- // Should not crash with null props
265
- try {
266
- await adapter!.renderToString(component);
267
- } catch {
268
- // Expected behavior - throws rather than crashes
269
- }
270
- });
271
- });
@@ -1,308 +0,0 @@
1
- /**
2
- * @flightdev/ui - Registry Integration Tests
3
- *
4
- * Tests for AdapterRegistry with dynamic loading and capability queries.
5
- * Validates tier filtering, capability queries, and adapter lifecycle.
6
- *
7
- * @module test/integration/registry.integration.test.ts
8
- */
9
-
10
- import { describe, it, expect, beforeEach, beforeAll } from 'vitest';
11
- import { adapterRegistry, registerBuiltinAdapters } from '../../src/core/registry.js';
12
- import { TIER_INFO } from '../../src/core/types.js';
13
-
14
- // ============================================================================
15
- // Registry Integration Tests
16
- // ============================================================================
17
-
18
- describe('Registry Integration Tests', () => {
19
- beforeAll(() => {
20
- registerBuiltinAdapters();
21
- });
22
-
23
- describe('Dynamic Adapter Loading', () => {
24
- it('should load adapters lazily on first access', async () => {
25
- const adapter = await adapterRegistry.get('react');
26
-
27
- expect(adapter).toBeDefined();
28
- expect(adapter?.id).toBe('react');
29
- });
30
-
31
- it('should return same instance on subsequent calls', async () => {
32
- const adapter1 = await adapterRegistry.get('vue');
33
- const adapter2 = await adapterRegistry.get('vue');
34
-
35
- expect(adapter1).toBe(adapter2);
36
- });
37
-
38
- it('should return undefined for non-existent adapters', async () => {
39
- const adapter = await adapterRegistry.get('non-existent-framework');
40
-
41
- expect(adapter).toBeUndefined();
42
- });
43
-
44
- it('should load all tier-1 adapters successfully', async () => {
45
- const tier1 = adapterRegistry.listByTier('tier-1');
46
-
47
- for (const id of tier1) {
48
- const adapter = await adapterRegistry.get(id);
49
- expect(adapter, `Adapter ${id} should load`).toBeDefined();
50
- expect(adapter?.tier).toBe('tier-1');
51
- }
52
- });
53
-
54
- it('should load all tier-2 adapters successfully', async () => {
55
- const tier2 = adapterRegistry.listByTier('tier-2');
56
- // Some adapters may fail to load due to missing peer dependencies in CI
57
- const availableAdapters = ['preact', 'lit', 'marko', 'mithril', 'inferno'];
58
-
59
- for (const id of availableAdapters) {
60
- if (tier2.includes(id)) {
61
- try {
62
- const adapter = await adapterRegistry.get(id);
63
- expect(adapter, `Adapter ${id} should load`).toBeDefined();
64
- expect(adapter?.tier).toBe('tier-2');
65
- } catch {
66
- // Skip adapters that fail due to missing peer dependencies
67
- }
68
- }
69
- }
70
- });
71
-
72
- it('should load all tier-3 adapters successfully', async () => {
73
- const tier3 = adapterRegistry.listByTier('tier-3');
74
-
75
- for (const id of tier3) {
76
- const adapter = await adapterRegistry.get(id);
77
- expect(adapter, `Adapter ${id} should load`).toBeDefined();
78
- expect(adapter?.tier).toBe('tier-3');
79
- }
80
- });
81
- });
82
-
83
- describe('Capability Queries', () => {
84
- it('should list adapters with streaming capability', () => {
85
- const streamingAdapters = adapterRegistry.listByCapability('streaming');
86
-
87
- expect(streamingAdapters).toContain('react');
88
- expect(streamingAdapters).toContain('vue');
89
- expect(streamingAdapters).toContain('solid');
90
- expect(streamingAdapters).toContain('qwik');
91
- expect(streamingAdapters).toContain('marko');
92
-
93
- // HTMX should not have streaming
94
- expect(streamingAdapters).not.toContain('htmx');
95
- });
96
-
97
- it('should list adapters with islands capability', () => {
98
- const islandsAdapters = adapterRegistry.listByCapability('islands');
99
-
100
- // Islands adapters vary by implementation
101
- // At minimum, some tier-1 adapters should support islands
102
- expect(Array.isArray(islandsAdapters)).toBe(true);
103
- });
104
-
105
- it('should list adapters with resumable capability', () => {
106
- const resumableAdapters = adapterRegistry.listByCapability('resumable');
107
-
108
- // Only Qwik has resumable hydration
109
- expect(resumableAdapters).toContain('qwik');
110
- expect(resumableAdapters).not.toContain('react');
111
- expect(resumableAdapters).not.toContain('vue');
112
- });
113
-
114
- it('should list adapters with serverComponents capability', () => {
115
- const rscAdapters = adapterRegistry.listByCapability('serverComponents');
116
-
117
- expect(rscAdapters).toContain('react');
118
- });
119
-
120
- it('should list adapters with SSG capability', () => {
121
- const ssgAdapters = adapterRegistry.listByCapability('ssg');
122
-
123
- // SSG capability should be available in some adapters
124
- expect(Array.isArray(ssgAdapters)).toBe(true);
125
- });
126
-
127
- it('should list adapters with CSR capability', () => {
128
- const csrAdapters = adapterRegistry.listByCapability('csr');
129
-
130
- // CSR capability should be available in some adapters
131
- expect(Array.isArray(csrAdapters)).toBe(true);
132
- });
133
- });
134
-
135
- describe('Tier Filtering', () => {
136
- it('should return exactly 6 tier-1 adapters', () => {
137
- const tier1 = adapterRegistry.listByTier('tier-1');
138
-
139
- expect(tier1.length).toBe(6);
140
- expect(tier1).toContain('react');
141
- expect(tier1).toContain('vue');
142
- expect(tier1).toContain('angular');
143
- expect(tier1).toContain('svelte');
144
- expect(tier1).toContain('solid');
145
- expect(tier1).toContain('qwik');
146
- });
147
-
148
- it('should return exactly 6 tier-2 adapters', () => {
149
- const tier2 = adapterRegistry.listByTier('tier-2');
150
-
151
- expect(tier2.length).toBe(6);
152
- expect(tier2).toContain('preact');
153
- expect(tier2).toContain('lit');
154
- expect(tier2).toContain('marko');
155
- expect(tier2).toContain('stencil');
156
- expect(tier2).toContain('mithril');
157
- expect(tier2).toContain('inferno');
158
- });
159
-
160
- it('should return exactly 6 tier-3 adapters', () => {
161
- const tier3 = adapterRegistry.listByTier('tier-3');
162
-
163
- expect(tier3.length).toBe(6);
164
- expect(tier3).toContain('htmx');
165
- expect(tier3).toContain('alpine');
166
- expect(tier3).toContain('hotwire');
167
- expect(tier3).toContain('stimulus');
168
- expect(tier3).toContain('petite-vue');
169
- expect(tier3).toContain('vanilla');
170
- });
171
-
172
- it('should have 18 total adapters', () => {
173
- const tier1 = adapterRegistry.listByTier('tier-1');
174
- const tier2 = adapterRegistry.listByTier('tier-2');
175
- const tier3 = adapterRegistry.listByTier('tier-3');
176
-
177
- expect(tier1.length + tier2.length + tier3.length).toBe(18);
178
- });
179
- });
180
-
181
- describe('Registry Has Check', () => {
182
- it('should return true for registered adapters', () => {
183
- expect(adapterRegistry.has('react')).toBe(true);
184
- expect(adapterRegistry.has('vue')).toBe(true);
185
- expect(adapterRegistry.has('htmx')).toBe(true);
186
- });
187
-
188
- it('should return false for unregistered adapters', () => {
189
- expect(adapterRegistry.has('unknown')).toBe(false);
190
- expect(adapterRegistry.has('')).toBe(false);
191
- expect(adapterRegistry.has('nextjs')).toBe(false);
192
- });
193
- });
194
-
195
- describe('TIER_INFO Metadata', () => {
196
- it('should have metadata for all tiers', () => {
197
- expect(TIER_INFO['tier-1']).toBeDefined();
198
- expect(TIER_INFO['tier-2']).toBeDefined();
199
- expect(TIER_INFO['tier-3']).toBeDefined();
200
- });
201
-
202
- it('should have meaningful names and descriptions', () => {
203
- expect(TIER_INFO['tier-1'].name.length).toBeGreaterThan(0);
204
- expect(TIER_INFO['tier-1'].description.length).toBeGreaterThan(0);
205
-
206
- expect(TIER_INFO['tier-2'].name.length).toBeGreaterThan(0);
207
- expect(TIER_INFO['tier-2'].description.length).toBeGreaterThan(0);
208
-
209
- expect(TIER_INFO['tier-3'].name.length).toBeGreaterThan(0);
210
- expect(TIER_INFO['tier-3'].description.length).toBeGreaterThan(0);
211
- });
212
- });
213
-
214
- describe('Cross-Tier Capability Analysis', () => {
215
- it('should show tier-1 has more capabilities than tier-3', async () => {
216
- const react = await adapterRegistry.get('react');
217
- const htmx = await adapterRegistry.get('htmx');
218
-
219
- expect(react).toBeDefined();
220
- expect(htmx).toBeDefined();
221
-
222
- // Count true capabilities
223
- const reactCaps = Object.values(react!.capabilities).filter(Boolean).length;
224
- const htmxCaps = Object.values(htmx!.capabilities).filter(Boolean).length;
225
-
226
- expect(reactCaps).toBeGreaterThan(htmxCaps);
227
- });
228
-
229
- it('should have consistent capability shape across all adapters', async () => {
230
- const adapters = [
231
- ...adapterRegistry.listByTier('tier-1'),
232
- ...adapterRegistry.listByTier('tier-2'),
233
- ...adapterRegistry.listByTier('tier-3'),
234
- ];
235
-
236
- for (const id of adapters) {
237
- try {
238
- const adapter = await adapterRegistry.get(id);
239
- if (adapter) {
240
- expect(adapter.capabilities).toHaveProperty('streaming');
241
- expect(adapter.capabilities).toHaveProperty('partialHydration');
242
- expect(adapter.capabilities).toHaveProperty('islands');
243
- expect(adapter.capabilities).toHaveProperty('resumable');
244
- expect(adapter.capabilities).toHaveProperty('ssg');
245
- expect(adapter.capabilities).toHaveProperty('csr');
246
- expect(adapter.capabilities).toHaveProperty('serverComponents');
247
- }
248
- } catch {
249
- // Skip adapters that fail due to missing peer dependencies
250
- }
251
- }
252
- });
253
- });
254
- });
255
-
256
- // ============================================================================
257
- // Adapter Lifecycle Tests
258
- // ============================================================================
259
-
260
- describe('Adapter Lifecycle', () => {
261
- beforeAll(() => {
262
- registerBuiltinAdapters();
263
- });
264
-
265
- it('all adapters should implement required methods', async () => {
266
- const adapters = [
267
- ...adapterRegistry.listByTier('tier-1'),
268
- ...adapterRegistry.listByTier('tier-2'),
269
- ...adapterRegistry.listByTier('tier-3'),
270
- ];
271
-
272
- for (const id of adapters) {
273
- try {
274
- const adapter = await adapterRegistry.get(id);
275
- if (adapter) {
276
- expect(typeof adapter.renderToString, `${id}.renderToString`).toBe('function');
277
- expect(typeof adapter.getHydrationScript, `${id}.getHydrationScript`).toBe('function');
278
- expect(typeof adapter.getClientEntry, `${id}.getClientEntry`).toBe('function');
279
- expect(typeof adapter.createIsland, `${id}.createIsland`).toBe('function');
280
- }
281
- } catch {
282
- // Skip adapters that fail due to missing peer dependencies
283
- }
284
- }
285
- });
286
-
287
- it('all adapters should have valid identity', async () => {
288
- const adapters = [
289
- ...adapterRegistry.listByTier('tier-1'),
290
- ...adapterRegistry.listByTier('tier-2'),
291
- ...adapterRegistry.listByTier('tier-3'),
292
- ];
293
-
294
- for (const id of adapters) {
295
- try {
296
- const adapter = await adapterRegistry.get(id);
297
- if (adapter) {
298
- expect(adapter.id, `${id}.id`).toBe(id);
299
- expect(adapter.name.length, `${id}.name`).toBeGreaterThan(0);
300
- expect(adapter.framework.length, `${id}.framework`).toBeGreaterThan(0);
301
- expect(['tier-1', 'tier-2', 'tier-3']).toContain(adapter.tier);
302
- }
303
- } catch {
304
- // Skip adapters that fail due to missing peer dependencies
305
- }
306
- }
307
- });
308
- });
package/tsconfig.json DELETED
@@ -1,22 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.json",
3
- "compilerOptions": {
4
- "outDir": "dist",
5
- "rootDir": ".",
6
- "noEmit": false,
7
- "noUnusedLocals": false,
8
- "noUnusedParameters": false,
9
- "jsx": "react-jsx",
10
- "types": [
11
- "vitest/globals"
12
- ]
13
- },
14
- "include": [
15
- "src/**/*",
16
- "test/**/*"
17
- ],
18
- "exclude": [
19
- "node_modules",
20
- "dist"
21
- ]
22
- }
package/tsup.config.ts DELETED
@@ -1,93 +0,0 @@
1
- import { defineConfig } from 'tsup';
2
-
3
- export default defineConfig({
4
- entry: [
5
- // Main entry
6
- 'src/index.ts',
7
-
8
- // Core module
9
- 'src/core/index.ts',
10
-
11
- // Tier 1 - Full Support
12
- 'src/adapters/tier-1/index.ts',
13
- 'src/adapters/tier-1/react.ts',
14
- 'src/adapters/tier-1/vue.ts',
15
- 'src/adapters/tier-1/angular.ts',
16
- 'src/adapters/tier-1/svelte.ts',
17
- 'src/adapters/tier-1/solid.ts',
18
- 'src/adapters/tier-1/qwik.ts',
19
-
20
- // Tier 2 - Standard Support
21
- 'src/adapters/tier-2/index.ts',
22
- 'src/adapters/tier-2/preact.ts',
23
- 'src/adapters/tier-2/lit.ts',
24
- 'src/adapters/tier-2/marko.ts',
25
- 'src/adapters/tier-2/stencil.ts',
26
- 'src/adapters/tier-2/mithril.ts',
27
- 'src/adapters/tier-2/inferno.ts',
28
-
29
- // Tier 3 - HTML-First
30
- 'src/adapters/tier-3/index.ts',
31
- 'src/adapters/tier-3/htmx.ts',
32
- 'src/adapters/tier-3/alpine.ts',
33
- 'src/adapters/tier-3/hotwire.ts',
34
- 'src/adapters/tier-3/stimulus.ts',
35
- 'src/adapters/tier-3/petite-vue.ts',
36
- 'src/adapters/tier-3/vanilla.ts',
37
- ],
38
- format: ['esm'],
39
- dts: {
40
- compilerOptions: {
41
- skipLibCheck: true,
42
- },
43
- },
44
- clean: true,
45
- target: 'node20',
46
- splitting: true,
47
- treeshake: true,
48
- external: [
49
- // Tier 1
50
- 'react',
51
- 'react-dom',
52
- 'react-dom/server',
53
- 'react-dom/client',
54
- 'vue',
55
- 'vue/server-renderer',
56
- '@angular/core',
57
- '@angular/platform-server',
58
- '@angular/platform-browser',
59
- 'svelte',
60
- 'svelte/server',
61
- 'svelte/compiler',
62
- 'solid-js',
63
- 'solid-js/web',
64
- '@builder.io/qwik',
65
- '@builder.io/qwik/server',
66
-
67
- // Tier 2
68
- 'preact',
69
- 'preact-render-to-string',
70
- 'lit',
71
- '@lit-labs/ssr',
72
- '@lit-labs/ssr/lib/render-result.js',
73
- 'marko',
74
- '@stencil/core',
75
- '@stencil/core/hydrate',
76
- 'mithril',
77
- 'mithril-node-render',
78
- 'inferno',
79
- 'inferno-server',
80
- 'inferno-create-element',
81
- 'inferno-hydrate',
82
-
83
- // Tier 3
84
- 'alpinejs',
85
- '@alpinejs/csp',
86
- '@hotwired/turbo',
87
- '@hotwired/stimulus',
88
- 'petite-vue',
89
-
90
- // Node.js
91
- 'stream',
92
- ],
93
- });