@qwik-custom-elements/adapter-stencil 1.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.
- package/LICENSE +21 -0
- package/README.md +420 -0
- package/dist/bundle-graph.json +1 -0
- package/dist/client/client-setup.d.ts +9 -0
- package/dist/client/client-setup.d.ts.map +1 -0
- package/dist/client/client-setup.test.d.ts +2 -0
- package/dist/client/client-setup.test.d.ts.map +1 -0
- package/dist/client/index.cjs +1 -0
- package/dist/client/index.d.ts +3 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +6 -0
- package/dist/client/stencil-csr-props.d.ts +2 -0
- package/dist/client/stencil-csr-props.d.ts.map +1 -0
- package/dist/client/stencil-csr-props.test.d.ts +2 -0
- package/dist/client/stencil-csr-props.test.d.ts.map +1 -0
- package/dist/client/stencil-csr.d.ts +10 -0
- package/dist/client/stencil-csr.d.ts.map +1 -0
- package/dist/client-setup-C_qW_ZSR.cjs +1 -0
- package/dist/client-setup-D-ffVtNL.js +53 -0
- package/dist/client-setup.ts_createStencilClientSetup_runSetup_6wDTmOSdSbc-CPKK-h2J.js +11 -0
- package/dist/client-setup.ts_createStencilClientSetup_runSetup_6wDTmOSdSbc-Dz0z3zer.cjs +1 -0
- package/dist/core.min-Qm7Mxv6F.js +1846 -0
- package/dist/core.min-vJ4M2jcU.cjs +2 -0
- package/dist/index.d.ts +84 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.qwik.cjs +8 -0
- package/dist/index.qwik.mjs +364 -0
- package/dist/index.test.d.ts +2 -0
- package/dist/index.test.d.ts.map +1 -0
- package/dist/preloader-Bietv0BS.js +118 -0
- package/dist/preloader-Cqc--uBU.cjs +1 -0
- package/dist/q-manifest.json +381 -0
- package/dist/qwikloader-C01zMTOC.js +102 -0
- package/dist/qwikloader-vFGnpgvG.cjs +2 -0
- package/dist/ssr/element-props-utils.d.ts +10 -0
- package/dist/ssr/element-props-utils.d.ts.map +1 -0
- package/dist/ssr/element-props-utils.test.d.ts +2 -0
- package/dist/ssr/element-props-utils.test.d.ts.map +1 -0
- package/dist/ssr/index.cjs +1 -0
- package/dist/ssr/index.d.ts +5 -0
- package/dist/ssr/index.d.ts.map +1 -0
- package/dist/ssr/index.js +29 -0
- package/dist/ssr/model.d.ts +49 -0
- package/dist/ssr/model.d.ts.map +1 -0
- package/dist/ssr/stencil-ssr.d.ts +14 -0
- package/dist/ssr/stencil-ssr.d.ts.map +1 -0
- package/dist/ssr/styles-core.d.ts +29 -0
- package/dist/ssr/styles-core.d.ts.map +1 -0
- package/dist/ssr/styles-core.test.d.ts +2 -0
- package/dist/ssr/styles-core.test.d.ts.map +1 -0
- package/dist/stencil-csr-B1U9s3VQ.js +24 -0
- package/dist/stencil-csr-D6zt1Am9.cjs +1 -0
- package/dist/stencil-csr.tsx_createStencilCSRComponent_component_pD3ekIZcUT0-ChAZ0hL3.js +37 -0
- package/dist/stencil-csr.tsx_createStencilCSRComponent_component_pD3ekIZcUT0-cGN__hqm.cjs +1 -0
- package/dist/stencil-csr.tsx_createStencilCSRComponent_component_useVisibleTask_1_dqWPXf9eNnk-BYiBxXW-.js +34 -0
- package/dist/stencil-csr.tsx_createStencilCSRComponent_component_useVisibleTask_1_dqWPXf9eNnk-sFN0uMI_.cjs +1 -0
- package/dist/stencil-csr.tsx_createStencilCSRComponent_component_useVisibleTask_y00qkhhKua8-BSsN2V78.cjs +1 -0
- package/dist/stencil-csr.tsx_createStencilCSRComponent_component_useVisibleTask_y00qkhhKua8-CF00O7hf.js +19 -0
- package/dist/stencil-ssr-BHjT94rd.js +118 -0
- package/dist/stencil-ssr-UlYtcG0-.cjs +1 -0
- package/dist/stencil-ssr.tsx_createStencilSSRBridgeComponent_component_IlVdOHKZfN0-46y8eTjO.cjs +1 -0
- package/dist/stencil-ssr.tsx_createStencilSSRBridgeComponent_component_IlVdOHKZfN0-BfqXBofh.js +42 -0
- package/dist/stencil-ssr.tsx_createStencilSSRBridgeComponent_component_useOnDocument_bvALMlewx7Q-DA73DRke.cjs +1 -0
- package/dist/stencil-ssr.tsx_createStencilSSRBridgeComponent_component_useOnDocument_bvALMlewx7Q-DdcskN1z.js +10 -0
- package/dist/stencil-ssr.tsx_createStencilSSRBridgeComponent_component_useTask_1_aXg7AuatGTc-61dSP-JG.cjs +1 -0
- package/dist/stencil-ssr.tsx_createStencilSSRBridgeComponent_component_useTask_1_aXg7AuatGTc-Byrz3fUp.js +34 -0
- package/dist/stencil-ssr.tsx_createStencilSSRBridgeComponent_component_useTask_IH8I3eLdwI0-BtIygb8E.js +12 -0
- package/dist/stencil-ssr.tsx_createStencilSSRBridgeComponent_component_useTask_IH8I3eLdwI0-DNQBT8Vc.cjs +1 -0
- package/package.json +53 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Dmitry A. Efimenko
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
# @qwik-custom-elements/adapter-stencil
|
|
2
|
+
|
|
3
|
+
Qwik runtime helpers for integrating Stencil custom elements.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
npm install @qwik-custom-elements/adapter-stencil
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Peer dependencies:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
npm install @builder.io/qwik @builder.io/qwik-city @stencil/core
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quickstart
|
|
18
|
+
|
|
19
|
+
Reference this adapter in your `qwik-custom-elements.config.json`:
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"projects": [
|
|
24
|
+
{
|
|
25
|
+
"id": "my-stencil-lib",
|
|
26
|
+
"adapter": "stencil",
|
|
27
|
+
"adapterPackage": "@qwik-custom-elements/adapter-stencil",
|
|
28
|
+
"source": {
|
|
29
|
+
"type": "PACKAGE_NAME",
|
|
30
|
+
"packageName": "my-stencil-lib"
|
|
31
|
+
},
|
|
32
|
+
"adapterOptions": {
|
|
33
|
+
"runtime": {
|
|
34
|
+
"loaderImport": "my-stencil-lib/loader",
|
|
35
|
+
"hydrateImport": "my-stencil-lib/hydrate"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"outDir": "./src/generated/stencil/ssr"
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Omit `hydrateImport` to generate a CSR-only (loader-only) surface without Stencil SSR.
|
|
45
|
+
|
|
46
|
+
Run `npx qwik-custom-elements` to generate Qwik wrappers from the Stencil component library.
|
|
47
|
+
|
|
48
|
+
See the [Manual Runtime Usage](#manual-runtime-usage) section below for direct API usage without the generator.
|
|
49
|
+
|
|
50
|
+
## Support Policy
|
|
51
|
+
|
|
52
|
+
This package follows semantic versioning. See [COMPATIBILITY.md](../../COMPATIBILITY.md) for tested combinations of adapter-stencil, Qwik, Stencil, and Node.js.
|
|
53
|
+
|
|
54
|
+
Breaking changes always include an explicit `BREAKING` section in the release notes and require an update to `COMPATIBILITY.md` before merging.
|
|
55
|
+
|
|
56
|
+
## Ownership Boundary
|
|
57
|
+
|
|
58
|
+
`@qwik-custom-elements/adapter-stencil` owns Stencil-specific generation behavior and runtime integration.
|
|
59
|
+
|
|
60
|
+
That ownership includes:
|
|
61
|
+
|
|
62
|
+
- Stencil capability metadata
|
|
63
|
+
- Stencil runtime import resolution and validation
|
|
64
|
+
- Stencil SSR probing and SSR bridge behavior
|
|
65
|
+
- adapter-owned generated barrels, runtime helper modules, wrapper modules, and file extensions
|
|
66
|
+
- framework-specific output shape decisions that must not live in core
|
|
67
|
+
|
|
68
|
+
Core may orchestrate the run and pass typed parsed component metadata into this adapter, but core should not branch on adapter identity to shape Stencil-generated output directly.
|
|
69
|
+
|
|
70
|
+
## Current Exports
|
|
71
|
+
|
|
72
|
+
This package exposes two runtime entrypoints:
|
|
73
|
+
|
|
74
|
+
- `@qwik-custom-elements/adapter-stencil/client`
|
|
75
|
+
- `createStencilClientSetup(...)`
|
|
76
|
+
- `createStencilCSRComponent()`
|
|
77
|
+
- `@qwik-custom-elements/adapter-stencil/ssr`
|
|
78
|
+
- `createStencilSSRComponent(...)`
|
|
79
|
+
- SSR model and style helpers
|
|
80
|
+
|
|
81
|
+
These APIs let an app or generated wrapper layer bootstrap Stencil custom elements on the client and render them through a Qwik SSR bridge when hydrate-backed SSR is available.
|
|
82
|
+
|
|
83
|
+
`createStencilCSRComponent` provides the client-only rendering bridge for loader-only generation. It renders the custom element tag directly, wires events on the client, projects slots, and does not depend on Stencil server rendering.
|
|
84
|
+
|
|
85
|
+
## Manual Runtime Usage
|
|
86
|
+
|
|
87
|
+
```tsx
|
|
88
|
+
import { $ } from '@builder.io/qwik';
|
|
89
|
+
import { createStencilClientSetup } from '@qwik-custom-elements/adapter-stencil/client';
|
|
90
|
+
import {
|
|
91
|
+
createStencilSSRComponent,
|
|
92
|
+
type StencilRenderToString,
|
|
93
|
+
} from '@qwik-custom-elements/adapter-stencil/ssr';
|
|
94
|
+
|
|
95
|
+
import { defineCustomElements } from '@acme/stencil-lib/loader';
|
|
96
|
+
|
|
97
|
+
const renderToString: StencilRenderToString = async (input, options) => {
|
|
98
|
+
const hydrateModuleId = '@acme/stencil-lib/hydrate';
|
|
99
|
+
const { renderToString } = await import(/* @vite-ignore */ hydrateModuleId);
|
|
100
|
+
return renderToString(input, options);
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
export const useAcmeClientSetup = createStencilClientSetup(
|
|
104
|
+
$(async () => {
|
|
105
|
+
await Promise.resolve(defineCustomElements());
|
|
106
|
+
}),
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
export const AcmeStencilComponent = createStencilSSRComponent(
|
|
110
|
+
$(renderToString),
|
|
111
|
+
);
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Source Types For Generation
|
|
115
|
+
|
|
116
|
+
The generator contract supports two source types for Stencil projects:
|
|
117
|
+
|
|
118
|
+
- `PACKAGE_NAME`
|
|
119
|
+
- `CEM`
|
|
120
|
+
|
|
121
|
+
The intended direction is that both source types can generate the same consumer-facing output shape when enough runtime information is available:
|
|
122
|
+
|
|
123
|
+
- a shared Stencil bridge/runtime module
|
|
124
|
+
- individual typed Qwik wrappers for each Stencil component
|
|
125
|
+
|
|
126
|
+
The difference between the two source types is input contract and discovery model, not desired output.
|
|
127
|
+
|
|
128
|
+
## `PACKAGE_NAME`
|
|
129
|
+
|
|
130
|
+
Use `PACKAGE_NAME` when the Stencil library is consumable as a package and you want package-aware discovery.
|
|
131
|
+
|
|
132
|
+
Example config:
|
|
133
|
+
|
|
134
|
+
```json
|
|
135
|
+
{
|
|
136
|
+
"projects": [
|
|
137
|
+
{
|
|
138
|
+
"id": "demo",
|
|
139
|
+
"adapter": "stencil",
|
|
140
|
+
"adapterPackage": "@qwik-custom-elements/adapter-stencil",
|
|
141
|
+
"source": {
|
|
142
|
+
"type": "PACKAGE_NAME",
|
|
143
|
+
"packageName": "@acme/stencil-lib"
|
|
144
|
+
},
|
|
145
|
+
"outDir": "./apps/qwik-demo/src/generated/acme",
|
|
146
|
+
"cleanOutput": true,
|
|
147
|
+
"adapterOptions": {
|
|
148
|
+
"runtime": {
|
|
149
|
+
"loaderImport": "@acme/stencil-lib/loader",
|
|
150
|
+
"hydrateImport": "@acme/stencil-lib/hydrate"
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
]
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Example config with an explicit manifest override:
|
|
159
|
+
|
|
160
|
+
```json
|
|
161
|
+
{
|
|
162
|
+
"projects": [
|
|
163
|
+
{
|
|
164
|
+
"id": "demo",
|
|
165
|
+
"adapter": "stencil",
|
|
166
|
+
"adapterPackage": "@qwik-custom-elements/adapter-stencil",
|
|
167
|
+
"source": {
|
|
168
|
+
"type": "PACKAGE_NAME",
|
|
169
|
+
"packageName": "@acme/stencil-lib",
|
|
170
|
+
"cemPath": "dist/custom-elements.json"
|
|
171
|
+
},
|
|
172
|
+
"outDir": "./apps/qwik-demo/src/generated/acme",
|
|
173
|
+
"cleanOutput": true,
|
|
174
|
+
"adapterOptions": {
|
|
175
|
+
"runtime": {
|
|
176
|
+
"loaderImport": "@acme/stencil-lib/loader",
|
|
177
|
+
"hydrateImport": "@acme/stencil-lib/hydrate"
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
]
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Why use `PACKAGE_NAME`:
|
|
186
|
+
|
|
187
|
+
- Best fit when the library is installed and consumed like a normal package.
|
|
188
|
+
- Lets the generator resolve the package root and discover the manifest automatically.
|
|
189
|
+
- Keeps config closer to the way end users actually import the library.
|
|
190
|
+
- Works well when package exports are the source of truth for runtime entrypoints.
|
|
191
|
+
|
|
192
|
+
## `CEM`
|
|
193
|
+
|
|
194
|
+
Use `CEM` when you want explicit control over the manifest and runtime import locations.
|
|
195
|
+
|
|
196
|
+
Example config:
|
|
197
|
+
|
|
198
|
+
```json
|
|
199
|
+
{
|
|
200
|
+
"projects": [
|
|
201
|
+
{
|
|
202
|
+
"id": "demo",
|
|
203
|
+
"adapter": "stencil",
|
|
204
|
+
"adapterPackage": "@qwik-custom-elements/adapter-stencil",
|
|
205
|
+
"source": {
|
|
206
|
+
"type": "CEM",
|
|
207
|
+
"path": "./vendor/acme/custom-elements.json"
|
|
208
|
+
},
|
|
209
|
+
"outDir": "./apps/qwik-demo/src/generated/acme",
|
|
210
|
+
"cleanOutput": true,
|
|
211
|
+
"adapterOptions": {
|
|
212
|
+
"runtime": {
|
|
213
|
+
"loaderImport": "@acme/stencil-lib/loader",
|
|
214
|
+
"hydrateImport": "@acme/stencil-lib/hydrate"
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
]
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Example config where runtime imports point at a project-local shim:
|
|
223
|
+
|
|
224
|
+
```json
|
|
225
|
+
{
|
|
226
|
+
"projects": [
|
|
227
|
+
{
|
|
228
|
+
"id": "demo",
|
|
229
|
+
"adapter": "stencil",
|
|
230
|
+
"adapterPackage": "@qwik-custom-elements/adapter-stencil",
|
|
231
|
+
"source": {
|
|
232
|
+
"type": "CEM",
|
|
233
|
+
"path": "./artifacts/acme/custom-elements.json"
|
|
234
|
+
},
|
|
235
|
+
"outDir": "./apps/qwik-demo/src/generated/acme",
|
|
236
|
+
"cleanOutput": true,
|
|
237
|
+
"adapterOptions": {
|
|
238
|
+
"runtime": {
|
|
239
|
+
"loaderImport": "./src/runtime/acme-loader",
|
|
240
|
+
"hydrateImport": "./src/runtime/acme-hydrate"
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
]
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Why use `CEM`:
|
|
249
|
+
|
|
250
|
+
- The Stencil library is not installed as a normal package.
|
|
251
|
+
- You want generation decoupled from package resolution.
|
|
252
|
+
- You need to point at a specific manifest artifact rather than rely on package discovery.
|
|
253
|
+
- Runtime imports come from a shim, wrapper, vendored output, or nonstandard location.
|
|
254
|
+
- You want explicit, reproducible control over both metadata and runtime entrypoints.
|
|
255
|
+
|
|
256
|
+
## Planned Runtime Discovery Rules
|
|
257
|
+
|
|
258
|
+
For Stencil generation, the runtime can use two imports in addition to component metadata:
|
|
259
|
+
|
|
260
|
+
- a loader import used on the client (`defineCustomElements`)
|
|
261
|
+
- a hydrate import used for SSR (`renderToString`)
|
|
262
|
+
|
|
263
|
+
The current contract is:
|
|
264
|
+
|
|
265
|
+
- `PACKAGE_NAME` resolves runtime imports to `<packageName>/loader` and `<packageName>/hydrate` by default.
|
|
266
|
+
- For `PACKAGE_NAME`, explicit `adapterOptions.runtime.loaderImport` and `adapterOptions.runtime.hydrateImport` overrides take precedence over those defaults. When an override is set, it must be a non-empty string.
|
|
267
|
+
- For `PACKAGE_NAME`, the resolved loader import must be package-resolvable before generation proceeds. Loader resolution failures stop the run with a deterministic loader-specific error.
|
|
268
|
+
- For `PACKAGE_NAME`, the resolved hydrate import is validated when provided or inferred. Hydrate resolution failures downgrade SSR availability and emit a hydrate-specific diagnostic instead of aborting loader-only generation.
|
|
269
|
+
- `CEM` requires `adapterOptions.runtime.loaderImport`.
|
|
270
|
+
- `CEM` may omit `adapterOptions.runtime.hydrateImport` when SSR hydrate support is unavailable or intentionally deferred.
|
|
271
|
+
- Core consumes the adapter-resolved runtime imports when invoking adapter SSR probing, so runtime resolution and SSR capability checks use the same resolved inputs.
|
|
272
|
+
|
|
273
|
+
`SSR available` has a specific meaning for Stencil projects:
|
|
274
|
+
|
|
275
|
+
- The resolved hydrate module can be imported by the probe, and the module exports `renderToString` as a function.
|
|
276
|
+
- If hydrate import fails or `renderToString` is missing/non-function, SSR is treated as unavailable.
|
|
277
|
+
- When SSR is unavailable but the loader import is valid, generation remains successful in loader-only mode with the CSR surface.
|
|
278
|
+
|
|
279
|
+
This keeps `PACKAGE_NAME` ergonomic while preserving `CEM` as an explicit-control mode for advanced or nonstandard setups.
|
|
280
|
+
|
|
281
|
+
## Generated Runtime Modules
|
|
282
|
+
|
|
283
|
+
For Stencil projects with a valid resolved loader import, generated client bootstrap remains valuable even when hydrate-backed SSR is unavailable.
|
|
284
|
+
|
|
285
|
+
The generated client module (`runtime-csr.generated.ts`) provides:
|
|
286
|
+
|
|
287
|
+
- a resolved `defineCustomElements` wrapper bound to the package-aware loader import
|
|
288
|
+
- `defineCustomElementsQrl`
|
|
289
|
+
- `useStencilClientSetup`
|
|
290
|
+
- `GeneratedStencilCSRComponent` — the client-only rendering bridge created by `createStencilCSRComponent()`
|
|
291
|
+
|
|
292
|
+
When a resolved hydrate import is also available, generation additionally emits `runtime-ssr.generated.ts` with a typed `renderToString` export that loads the resolved hydrate runtime through the same Vite-ignored dynamic import boundary used for SSR-safe demo integration.
|
|
293
|
+
|
|
294
|
+
For `PACKAGE_NAME`, those runtime imports may come from package-aware defaults or explicit overrides. For `CEM`, they come from the explicit `adapterOptions.runtime` contract. This keeps generated runtime modules aligned with the same resolved runtime import contract already used for validation and SSR probing.
|
|
295
|
+
|
|
296
|
+
The generated runtime exposes two capability-specific consumer surfaces when runtime modes differ materially:
|
|
297
|
+
|
|
298
|
+
- a CSR surface for loader-only generation that boots the client runtime and backs wrappers with `createStencilCSRComponent`
|
|
299
|
+
- an SSR surface for hydrate-capable generation that includes the hydrate bridge and backs wrappers with `createStencilSSRComponent`
|
|
300
|
+
|
|
301
|
+
The runtime leaf split is intentional:
|
|
302
|
+
|
|
303
|
+
- `runtime-csr.generated.ts` is client-reachable and must remain loader-only.
|
|
304
|
+
- `runtime-ssr.generated.ts` owns the hydrate-backed `renderToString` bridge and keeps hydrate loading behind a dynamic import boundary.
|
|
305
|
+
|
|
306
|
+
Generation mode depends on which resolved runtime imports are actually available, but the final Issue `#34` contract should not require loader-only wrappers to target the same bridge/runtime surface as SSR-capable wrappers:
|
|
307
|
+
|
|
308
|
+
- Full SSR mode: both loader and hydrate resolve, so generation emits an SSR-capable surface whose wrappers render through `createStencilSSRComponent`.
|
|
309
|
+
- Loader-only mode: loader resolves but hydrate does not, so generation still emits a client-capable surface, but that surface should be backed by `createStencilCSRComponent` rather than a degraded SSR bridge.
|
|
310
|
+
|
|
311
|
+
When hydrate resolution fails, the client runtime module is still generated from the loader import so loader-only fallback flows remain usable.
|
|
312
|
+
|
|
313
|
+
## Generated Wrapper Artifacts
|
|
314
|
+
|
|
315
|
+
When the generator has enough Stencil runtime information, `@qwik-custom-elements/adapter-stencil` owns the full generated surface under the target `outDir`.
|
|
316
|
+
|
|
317
|
+
For equivalent resolved runtime inputs, `PACKAGE_NAME` and `CEM` projects produce the same consumer-facing wrapper contract. CSR and SSR generation expose distinct surfaces when their runtime behavior diverges.
|
|
318
|
+
|
|
319
|
+
The generated surface uses a flat structure:
|
|
320
|
+
|
|
321
|
+
- `index.ts`
|
|
322
|
+
- Barrel that re-exports each generated Qwik wrapper plus the shared runtime helpers.
|
|
323
|
+
- `runtime.ts`
|
|
324
|
+
- Stable app-facing barrel that re-exports the generated client and SSR runtime leaves.
|
|
325
|
+
- `runtime-csr.generated.ts`
|
|
326
|
+
- Client bootstrap module that wires `defineCustomElements` into Qwik-friendly helpers and exports `GeneratedStencilCSRComponent`.
|
|
327
|
+
- `runtime-ssr.generated.ts` (emitted only when hydrate is available)
|
|
328
|
+
- SSR-only bridge helpers that keep hydrate loading behind a dynamic import boundary.
|
|
329
|
+
- `*.tsx`
|
|
330
|
+
- One generated Qwik wrapper per discovered Stencil component.
|
|
331
|
+
|
|
332
|
+
The current behavior:
|
|
333
|
+
|
|
334
|
+
- loader-only generation emits a CSR surface backed by `createStencilCSRComponent` (no `runtime-ssr.generated.ts`, wrappers render through `GeneratedStencilCSRComponent`)
|
|
335
|
+
- SSR-capable generation additionally emits `runtime-ssr.generated.ts` and backs wrappers with `GeneratedStencilComponent` from the SSR surface
|
|
336
|
+
- exact surface paths are implementation detail
|
|
337
|
+
- wrappers in both modes preserve the same public interface for typed props, typed `onEvent$` bindings, and slot projection
|
|
338
|
+
|
|
339
|
+
Generated wrapper components follow a stable contract:
|
|
340
|
+
|
|
341
|
+
- Prop typing starts from available CEM attribute and member metadata.
|
|
342
|
+
- Custom events become typed `onEvent$` QRL props when event metadata is available.
|
|
343
|
+
- Wrapper components call `useStencilClientSetup()` so client bootstrap stays centralized in generated runtime output.
|
|
344
|
+
- When SSR runtime is available, wrappers render through `GeneratedStencilComponent` from the SSR surface backed by `createStencilSSRComponent`.
|
|
345
|
+
- When only the loader runtime is available, wrappers render through `GeneratedStencilCSRComponent` from the CSR surface backed by `createStencilCSRComponent`, rendering the custom-element tag directly while preserving props, typed `onEvent$` bindings, slot metadata, and client bootstrap.
|
|
346
|
+
- Slot metadata is projected with deterministic Qwik `<Slot />` output, including named slot support when the source metadata declares it.
|
|
347
|
+
|
|
348
|
+
Example generated surface (SSR-capable mode):
|
|
349
|
+
|
|
350
|
+
```text
|
|
351
|
+
src/generated/
|
|
352
|
+
index.ts
|
|
353
|
+
runtime.ts
|
|
354
|
+
runtime-csr.generated.ts
|
|
355
|
+
runtime-ssr.generated.ts
|
|
356
|
+
de-button.tsx
|
|
357
|
+
de-alert.tsx
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
In loader-only mode, `runtime-ssr.generated.ts` is not emitted, and wrapper files render through `GeneratedStencilCSRComponent` instead of `GeneratedStencilComponent`.
|
|
361
|
+
|
|
362
|
+
Example consumer usage:
|
|
363
|
+
|
|
364
|
+
```tsx
|
|
365
|
+
import { $, component$ } from '@builder.io/qwik';
|
|
366
|
+
|
|
367
|
+
import { QwikDeAlert, QwikDeButton } from './generated';
|
|
368
|
+
|
|
369
|
+
export default component$(() => {
|
|
370
|
+
const handleTripleClick$ = $(() => {
|
|
371
|
+
console.log('triple click');
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
return (
|
|
375
|
+
<>
|
|
376
|
+
<QwikDeButton size="md" onTripleClick$={handleTripleClick$}>
|
|
377
|
+
Generated Button
|
|
378
|
+
</QwikDeButton>
|
|
379
|
+
|
|
380
|
+
<QwikDeAlert heading="Generated Alert">
|
|
381
|
+
<span>Default slot content</span>
|
|
382
|
+
<span q:slot="footer">Named slot content</span>
|
|
383
|
+
</QwikDeAlert>
|
|
384
|
+
</>
|
|
385
|
+
);
|
|
386
|
+
});
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
The checked-in demo route at `apps/qwik-demo/src/routes/stencil/ssr/wrappers/` is the reference integration path for this generated surface. It validates that generated wrappers, generated runtime setup, typed event handlers, and slot projection all work together without a handwritten app-local bridge layer.
|
|
390
|
+
|
|
391
|
+
The checked-in CSR demo routes at `apps/qwik-demo/src/routes/stencil/csr/` consume CSR-generated output directly rather than re-exporting or aliasing the SSR demo routes.
|
|
392
|
+
|
|
393
|
+
## SSR Fallback Behavior
|
|
394
|
+
|
|
395
|
+
Generation supports SSR where available but does not require SSR availability to produce useful wrappers.
|
|
396
|
+
|
|
397
|
+
The behavior for Stencil projects is:
|
|
398
|
+
|
|
399
|
+
- If both loader and hydrate are available, generation emits an SSR-capable surface with both `runtime-csr.generated.ts` and `runtime-ssr.generated.ts`, and wrappers render through `createStencilSSRComponent`.
|
|
400
|
+
- If only loader is available and hydrate/SSR support is unavailable, generation still emits a client-capable CSR surface backed by `createStencilCSRComponent`. The CSR surface omits `runtime-ssr.generated.ts` entirely.
|
|
401
|
+
|
|
402
|
+
Consumers can treat those two modes as separate capability-specific surfaces with the same wrapper-facing contract:
|
|
403
|
+
|
|
404
|
+
- Full SSR mode exposes an SSR-capable surface whose wrappers render through `createStencilSSRComponent`.
|
|
405
|
+
- Loader-only mode exposes a CSR surface whose wrappers render through `createStencilCSRComponent` and never depend on Stencil server rendering.
|
|
406
|
+
- In both modes, wrapper props, event bindings, slot projection, and client bootstrap stay adapter-owned and deterministic.
|
|
407
|
+
|
|
408
|
+
The loader-only fallback still provides value to consumers because generated Qwik components remain:
|
|
409
|
+
|
|
410
|
+
- typed
|
|
411
|
+
- consistent across components
|
|
412
|
+
- event-aware
|
|
413
|
+
- slot-aware
|
|
414
|
+
- ready for client-side Stencil upgrade
|
|
415
|
+
|
|
416
|
+
## Documentation Expectations
|
|
417
|
+
|
|
418
|
+
Consumer-facing behavior for source types, runtime discovery, SSR fallback, and generated output shape should be documented whenever changes land in this adapter or the core generator.
|
|
419
|
+
|
|
420
|
+
Architecture ownership changes should also keep this README aligned with the package-level boundary: Stencil-specific generated output belongs here, not in `@qwik-custom-elements/core`.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
["../client-setup-C_qW_ZSR.cjs",9,-9,4,"../client-setup.ts_createStencilClientSetup_runSetup_6wDTmOSdSbc-Dz0z3zer.cjs",0,"../client/index.cjs",0,12,"../core.min-vJ4M2jcU.cjs","../ssr/index.cjs",25,"../stencil-csr-D6zt1Am9.cjs",9,-9,16,"../stencil-csr.tsx_createStencilCSRComponent_component_pD3ekIZcUT0-cGN__hqm.cjs",9,-8,21,23,"../stencil-csr.tsx_createStencilCSRComponent_component_useVisibleTask_1_dqWPXf9eNnk-sFN0uMI_.cjs",12,"../stencil-csr.tsx_createStencilCSRComponent_component_useVisibleTask_y00qkhhKua8-BSsN2V78.cjs",9,"../stencil-ssr-UlYtcG0-.cjs",9,-9,29,"../stencil-ssr.tsx_createStencilSSRBridgeComponent_component_IlVdOHKZfN0-46y8eTjO.cjs",9,-8,38,40,-6,36,"../stencil-ssr.tsx_createStencilSSRBridgeComponent_component_useOnDocument_bvALMlewx7Q-DA73DRke.cjs",9,"../stencil-ssr.tsx_createStencilSSRBridgeComponent_component_useTask_1_aXg7AuatGTc-61dSP-JG.cjs",25,"../stencil-ssr.tsx_createStencilSSRBridgeComponent_component_useTask_IH8I3eLdwI0-DNQBT8Vc.cjs",10,"IH8I3eLdwI0",-8,40,"aXg7AuatGTc",-8,38,"dqWPXf9eNnk",-8,21,"y00qkhhKua8",-8,23,"IlVdOHKZfN0",-7,29,"pD3ekIZcUT0",-7,16,"6wDTmOSdSbc",-6,4,"bvALMlewx7Q",-6,36]
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type QRL } from '@builder.io/qwik';
|
|
2
|
+
type DefineCustomElementsInput = QRL<() => Promise<void>> | (() => Promise<void>);
|
|
3
|
+
/**
|
|
4
|
+
* Creates a client-side setup hook for Stencil components.
|
|
5
|
+
* Promotes SSR-emitted styles into document head, then registers custom elements.
|
|
6
|
+
*/
|
|
7
|
+
export declare function createStencilClientSetup(defineCustomElementsInput?: DefineCustomElementsInput): () => void;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=client-setup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-setup.d.ts","sourceRoot":"","sources":["../../src/client/client-setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAS9D,KAAK,yBAAyB,GAC1B,GAAG,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,GACxB,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;AA2H1B;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,yBAAyB,CAAC,EAAE,yBAAyB,cAgCtD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-setup.test.d.ts","sourceRoot":"","sources":["../../src/client/client-setup.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("../client-setup-C_qW_ZSR.cjs"),t=require("../stencil-csr-D6zt1Am9.cjs");exports.createStencilClientSetup=e.createStencilClientSetup;exports.createStencilCSRComponent=t.createStencilCSRComponent;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,EAAE,yBAAyB,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stencil-csr-props.d.ts","sourceRoot":"","sources":["../../src/client/stencil-csr-props.ts"],"names":[],"mappings":"AAUA,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,WAAW,GAAG,SAAS,EAC7B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,QAa3C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stencil-csr-props.test.d.ts","sourceRoot":"","sources":["../../src/client/stencil-csr-props.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type QRL } from '@builder.io/qwik';
|
|
2
|
+
export interface StencilCSRProps {
|
|
3
|
+
tagName: string;
|
|
4
|
+
props?: Record<string, unknown>;
|
|
5
|
+
events?: Record<string, QRL<(...args: any[]) => void>>;
|
|
6
|
+
slots?: string[];
|
|
7
|
+
[key: string]: unknown;
|
|
8
|
+
}
|
|
9
|
+
export declare function createStencilCSRComponent(): import("@builder.io/qwik").Component<StencilCSRProps>;
|
|
10
|
+
//# sourceMappingURL=stencil-csr.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stencil-csr.d.ts","sourceRoot":"","sources":["../../src/client/stencil-csr.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,GAAG,EACT,MAAM,kBAAkB,CAAC;AAwC1B,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC;IACvD,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,wBAAgB,yBAAyB,0DA0ExC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const i=require("./core.min-vJ4M2jcU.cjs"),r="__qce_stencil_client_setup_done__",s=new Map;let u=0;function a(e){if(!e)return;const t=`stencil-client-setup-${++u}`;return s.set(t,e),t}async function d(e){if(e)return typeof e=="object"&&e!==null&&"resolve"in e&&typeof e.resolve=="function"?e.resolve():e}async function S(e){const t=document.querySelectorAll("style[sty-id]"),n=new Set;for(const o of t)if(o.parentElement!==document.head){const c=o.textContent??"";n.has(c)?o.remove():(document.head.appendChild(o),n.add(c))}e&&await e()}function f(e){const t=globalThis,n=t[r];if(n===!0)return Promise.resolve();if(typeof n=="object"&&n!==null&&"then"in n&&typeof n.then=="function")return n;const o=(async()=>{const c=await d(e);await S(c)})();return t[r]=o,o.then(()=>{t[r]=!0}).catch(c=>{throw delete t[r],c})}async function l(e,t){const o=(e==null?void 0:s.get(e))??t;await f(o).catch(c=>{console.error(c)})}function p(e){const t=a(e),n=e!=null&&"$symbol$"in Object(e)?e:void 0,o=i.Ls(()=>Promise.resolve().then(()=>require("./client-setup.ts_createStencilClientSetup_runSetup_6wDTmOSdSbc-Dz0z3zer.cjs")),"s_6wDTmOSdSbc",[t,n]);return()=>{i.Re("load",o),typeof document<"u"&&document.readyState!=="loading"&&l(t,n)}}exports.createStencilClientSetup=p;exports.executeStencilClientSetup=l;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { R as i, L as l } from "./core.min-Qm7Mxv6F.js";
|
|
2
|
+
const r = "__qce_stencil_client_setup_done__", s = /* @__PURE__ */ new Map();
|
|
3
|
+
let u = 0;
|
|
4
|
+
function a(e) {
|
|
5
|
+
if (!e) return;
|
|
6
|
+
const t = `stencil-client-setup-${++u}`;
|
|
7
|
+
return s.set(t, e), t;
|
|
8
|
+
}
|
|
9
|
+
async function d(e) {
|
|
10
|
+
if (e)
|
|
11
|
+
return typeof e == "object" && e !== null && "resolve" in e && typeof e.resolve == "function" ? e.resolve() : e;
|
|
12
|
+
}
|
|
13
|
+
async function f(e) {
|
|
14
|
+
const t = document.querySelectorAll("style[sty-id]"), n = /* @__PURE__ */ new Set();
|
|
15
|
+
for (const o of t) if (o.parentElement !== document.head) {
|
|
16
|
+
const c = o.textContent ?? "";
|
|
17
|
+
n.has(c) ? o.remove() : (document.head.appendChild(o), n.add(c));
|
|
18
|
+
}
|
|
19
|
+
e && await e();
|
|
20
|
+
}
|
|
21
|
+
function S(e) {
|
|
22
|
+
const t = globalThis, n = t[r];
|
|
23
|
+
if (n === !0) return Promise.resolve();
|
|
24
|
+
if (typeof n == "object" && n !== null && "then" in n && typeof n.then == "function") return n;
|
|
25
|
+
const o = (async () => {
|
|
26
|
+
const c = await d(e);
|
|
27
|
+
await f(c);
|
|
28
|
+
})();
|
|
29
|
+
return t[r] = o, o.then(() => {
|
|
30
|
+
t[r] = !0;
|
|
31
|
+
}).catch((c) => {
|
|
32
|
+
throw delete t[r], c;
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
async function p(e, t) {
|
|
36
|
+
const o = (e == null ? void 0 : s.get(e)) ?? t;
|
|
37
|
+
await S(o).catch((c) => {
|
|
38
|
+
console.error(c);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
function m(e) {
|
|
42
|
+
const t = a(e), n = e != null && "$symbol$" in Object(e) ? e : void 0, o = /* @__PURE__ */ l(() => import("./client-setup.ts_createStencilClientSetup_runSetup_6wDTmOSdSbc-CPKK-h2J.js"), "s_6wDTmOSdSbc", [
|
|
43
|
+
t,
|
|
44
|
+
n
|
|
45
|
+
]);
|
|
46
|
+
return () => {
|
|
47
|
+
i("load", o), typeof document < "u" && document.readyState !== "loading" && p(t, n);
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
export {
|
|
51
|
+
m as c,
|
|
52
|
+
p as e
|
|
53
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { v as o } from "./core.min-Qm7Mxv6F.js";
|
|
2
|
+
import { x as p } from "./core.min-Qm7Mxv6F.js";
|
|
3
|
+
import { e as n } from "./client-setup-D-ffVtNL.js";
|
|
4
|
+
const m = async () => {
|
|
5
|
+
const [t, e] = o();
|
|
6
|
+
await n(t, e);
|
|
7
|
+
};
|
|
8
|
+
export {
|
|
9
|
+
p as _hW,
|
|
10
|
+
m as s_6wDTmOSdSbc
|
|
11
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./core.min-vJ4M2jcU.cjs"),c=require("./client-setup-C_qW_ZSR.cjs"),i=async()=>{const[t,n]=e.ve();await c.executeStencilClientSetup(t,n)};exports._hW=e.xe;exports.s_6wDTmOSdSbc=i;
|