@web-widget/vue 3.0.0-beta.2 → 3.0.0-beta.5
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/dist/chunk-ER6EL6Y7.js +174 -0
- package/dist/types-Q7wIvDbF.d.ts +48 -0
- package/dist/vue.adapter.client.d.ts +5 -4
- package/dist/vue.adapter.client.js +9 -8
- package/dist/vue.adapter.server.d.ts +5 -4
- package/dist/vue.adapter.server.js +24 -7
- package/dist/vue.d.ts +3 -3
- package/dist/vue.transform.d.ts +11 -0
- package/dist/vue.transform.js +13 -0
- package/package.json +49 -31
- package/dist/chunk-7KXT6LS2.js +0 -178
- package/dist/types-BY8s0m9C.d.ts +0 -85
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
// src/error-handler.ts
|
|
2
|
+
import { cacheProviderIsLoading } from "@web-widget/helpers/cache";
|
|
3
|
+
function installErrorHandler(app, callback, throwUnhandledErrorInProduction = false) {
|
|
4
|
+
app.config.throwUnhandledErrorInProduction = throwUnhandledErrorInProduction;
|
|
5
|
+
app.config.errorHandler = (err, instance, info) => {
|
|
6
|
+
if (cacheProviderIsLoading(err)) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
app.config.warnHandler = () => {
|
|
10
|
+
};
|
|
11
|
+
callback(err);
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// src/components.ts
|
|
16
|
+
import { WebWidgetRenderer } from "@web-widget/web-widget";
|
|
17
|
+
import {
|
|
18
|
+
h,
|
|
19
|
+
cloneVNode,
|
|
20
|
+
defineComponent,
|
|
21
|
+
Suspense,
|
|
22
|
+
useAttrs,
|
|
23
|
+
getCurrentInstance,
|
|
24
|
+
ref,
|
|
25
|
+
onErrorCaptured
|
|
26
|
+
} from "vue";
|
|
27
|
+
function renderLightChildren(slots) {
|
|
28
|
+
return Object.entries(slots).flatMap(
|
|
29
|
+
([name, render]) => render ? render().map(
|
|
30
|
+
(node) => name === "default" ? node : cloneVNode(node, { slot: name })
|
|
31
|
+
) : []
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
var ServerWebWidget = /* @__PURE__ */ defineComponent({
|
|
35
|
+
name: "ServerWebWidget",
|
|
36
|
+
props: {
|
|
37
|
+
errorFallback: {
|
|
38
|
+
type: Object,
|
|
39
|
+
default: null
|
|
40
|
+
},
|
|
41
|
+
renderer: {
|
|
42
|
+
type: Object,
|
|
43
|
+
required: true
|
|
44
|
+
},
|
|
45
|
+
renderChildren: {
|
|
46
|
+
type: Function,
|
|
47
|
+
required: true
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
async setup({ renderer, errorFallback, renderChildren }, { slots }) {
|
|
51
|
+
const parent = getCurrentInstance();
|
|
52
|
+
const children = Object.keys(slots).length ? await renderChildren(renderLightChildren(slots), parent) : "";
|
|
53
|
+
const tag = renderer.localName;
|
|
54
|
+
const attrs = renderer.attributes;
|
|
55
|
+
const innerHTML = await renderer.renderInnerHTMLToString({ children }).catch((err) => {
|
|
56
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
57
|
+
console.error("[VueWidget] Rendering error:", error);
|
|
58
|
+
return error;
|
|
59
|
+
});
|
|
60
|
+
if (innerHTML instanceof Error) {
|
|
61
|
+
return () => errorFallback;
|
|
62
|
+
}
|
|
63
|
+
return () => h(tag, { ...attrs, innerHTML });
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
function resolveFallback(fallback) {
|
|
67
|
+
var _a;
|
|
68
|
+
if (fallback !== null && typeof fallback === "object" && !("__v_isVNode" in fallback) && ("pending" in fallback || "error" in fallback)) {
|
|
69
|
+
const obj = fallback;
|
|
70
|
+
return {
|
|
71
|
+
pendingFallback: obj.pending,
|
|
72
|
+
errorFallback: (_a = obj.error) != null ? _a : obj.pending
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
pendingFallback: fallback,
|
|
77
|
+
errorFallback: fallback
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function createWidgetAdapter(renderChildren) {
|
|
81
|
+
return (loader, options = {}) => defineComponent({
|
|
82
|
+
name: "VueWidget",
|
|
83
|
+
inheritAttrs: false,
|
|
84
|
+
props: {
|
|
85
|
+
widget: {
|
|
86
|
+
type: Object,
|
|
87
|
+
default: () => ({})
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
setup({ widget }, { slots }) {
|
|
91
|
+
const { fallback, id, loading = options.loading, clientOnly } = widget;
|
|
92
|
+
const { pendingFallback, errorFallback } = resolveFallback(fallback);
|
|
93
|
+
const renderOptions = {
|
|
94
|
+
...options,
|
|
95
|
+
clientOnly: widget.clientOnly,
|
|
96
|
+
id,
|
|
97
|
+
loading: loading != null ? loading : options.loading,
|
|
98
|
+
serverOnly: widget.serverOnly
|
|
99
|
+
};
|
|
100
|
+
const attrs = { ...useAttrs() };
|
|
101
|
+
const slot = typeof attrs.slot === "string" ? attrs.slot : void 0;
|
|
102
|
+
delete attrs.slot;
|
|
103
|
+
const data = attrs;
|
|
104
|
+
const renderer = new WebWidgetRenderer(loader, {
|
|
105
|
+
...renderOptions,
|
|
106
|
+
data,
|
|
107
|
+
slot
|
|
108
|
+
});
|
|
109
|
+
if (renderer.opaqueInnerHTML !== void 0) {
|
|
110
|
+
return () => {
|
|
111
|
+
const lightChildren = Object.keys(slots).length ? renderLightChildren(slots) : [];
|
|
112
|
+
return h(
|
|
113
|
+
renderer.localName,
|
|
114
|
+
{
|
|
115
|
+
...renderer.attributes,
|
|
116
|
+
...lightChildren.length === 0 ? { innerHTML: renderer.opaqueInnerHTML } : null
|
|
117
|
+
},
|
|
118
|
+
lightChildren.length ? lightChildren : void 0
|
|
119
|
+
);
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
if (clientOnly && pendingFallback) {
|
|
123
|
+
return () => h(
|
|
124
|
+
renderer.localName,
|
|
125
|
+
renderer.attributes,
|
|
126
|
+
h(
|
|
127
|
+
renderer.pendingBoundary.localName,
|
|
128
|
+
{
|
|
129
|
+
"aria-busy": renderer.pendingBoundary.ariaBusy,
|
|
130
|
+
slot: renderer.pendingBoundary.slot,
|
|
131
|
+
style: { display: renderer.pendingBoundary.display }
|
|
132
|
+
},
|
|
133
|
+
pendingFallback
|
|
134
|
+
)
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
if (!renderChildren) {
|
|
138
|
+
throw new TypeError("Missing server children renderer.");
|
|
139
|
+
}
|
|
140
|
+
const error = ref(null);
|
|
141
|
+
onErrorCaptured((err) => {
|
|
142
|
+
error.value = err;
|
|
143
|
+
return false;
|
|
144
|
+
});
|
|
145
|
+
return () => {
|
|
146
|
+
if (error.value && errorFallback) {
|
|
147
|
+
return errorFallback;
|
|
148
|
+
}
|
|
149
|
+
return h(
|
|
150
|
+
Suspense,
|
|
151
|
+
{},
|
|
152
|
+
{
|
|
153
|
+
default: h(
|
|
154
|
+
ServerWebWidget,
|
|
155
|
+
{
|
|
156
|
+
errorFallback,
|
|
157
|
+
renderChildren,
|
|
158
|
+
renderer
|
|
159
|
+
},
|
|
160
|
+
slots
|
|
161
|
+
),
|
|
162
|
+
fallback: pendingFallback
|
|
163
|
+
}
|
|
164
|
+
);
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export {
|
|
171
|
+
installErrorHandler,
|
|
172
|
+
resolveFallback,
|
|
173
|
+
createWidgetAdapter
|
|
174
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { WidgetHostProps, WidgetContainerProps, WidgetContainerOptions, ExtractWidgetProps, WidgetModuleLoader } from '@web-widget/schema';
|
|
2
|
+
import { DefineComponent, VNode, App, Component } from 'vue';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A Vue component wrapping a widget, with props `T` plus container config.
|
|
6
|
+
*/
|
|
7
|
+
type VueWidgetComponent<T = unknown> = DefineComponent<T & WidgetHostProps & {
|
|
8
|
+
widget?: VueWidgetContainerProps;
|
|
9
|
+
}>;
|
|
10
|
+
type VueWidgetContainerProps = WidgetContainerProps<VNode>;
|
|
11
|
+
/**
|
|
12
|
+
* Resolve a WidgetFallback into separate pending and error VNodes.
|
|
13
|
+
* - `VNode` — used for both pending and error.
|
|
14
|
+
* - `{ pending?, error? }` — specify independently; `error` defaults to `pending`.
|
|
15
|
+
*/
|
|
16
|
+
declare function resolveFallback(fallback: VueWidgetContainerProps['fallback']): {
|
|
17
|
+
pendingFallback: VNode;
|
|
18
|
+
errorFallback: VNode;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Container function (AdapterModule contract).
|
|
22
|
+
*
|
|
23
|
+
* Wraps a widget module loader into a Vue component with props type
|
|
24
|
+
* inference from the source module's default export.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* import { widget } from '@web-widget/vue/adapter';
|
|
29
|
+
*
|
|
30
|
+
* const Counter = widget(() => import('./Counter@widget.vue'));
|
|
31
|
+
* // ^? VueWidgetComponent<{ count: number }>
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
interface VueWidgetFactory {
|
|
35
|
+
<M>(loader: () => Promise<M>, options?: WidgetContainerOptions): VueWidgetComponent<ExtractWidgetProps<M>>;
|
|
36
|
+
<Props>(loader: WidgetModuleLoader, options?: WidgetContainerOptions): VueWidgetComponent<Props>;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
interface CreateVueRenderOptions {
|
|
40
|
+
onCreatedApp?: (app: App<Element>, context: {
|
|
41
|
+
container?: Element | DocumentFragment;
|
|
42
|
+
data: any;
|
|
43
|
+
progressive?: boolean;
|
|
44
|
+
recovering?: boolean;
|
|
45
|
+
}, component: Component, props: any) => Promise<void>;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export { type CreateVueRenderOptions as C, type VueWidgetFactory as V, type VueWidgetComponent as a, type VueWidgetContainerProps as b, resolveFallback as r };
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import * as _web_widget_schema from '@web-widget/schema';
|
|
2
|
+
export { WidgetContainerOptions } from '@web-widget/schema';
|
|
3
|
+
import { C as CreateVueRenderOptions, V as VueWidgetFactory } from './types-Q7wIvDbF.js';
|
|
4
|
+
export { a as VueWidgetComponent, b as VueWidgetContainerProps, r as resolveFallback } from './types-Q7wIvDbF.js';
|
|
2
5
|
import { Component } from 'vue';
|
|
3
|
-
import { C as CreateVueRenderOptions } from './types-BY8s0m9C.js';
|
|
4
|
-
export { D as DefineWebWidgetOptions, V as VueWidgetComponent, W as WidgetContainerConfig, a as WidgetFallback, c as container, r as resolveFallback } from './types-BY8s0m9C.js';
|
|
5
6
|
export { asReactWidget, toReact } from './vue.js';
|
|
6
|
-
import '@web-widget/web-widget';
|
|
7
7
|
import '@web-widget/react/adapter';
|
|
8
8
|
|
|
9
|
+
declare const widget: VueWidgetFactory;
|
|
9
10
|
declare const createVueRender: ({ onCreatedApp, }?: CreateVueRenderOptions) => _web_widget_schema.ClientRender<Component, unknown, _web_widget_schema.ClientRenderOptions, void | _web_widget_schema.ClientRenderResult<unknown>>;
|
|
10
11
|
/**@deprecated Please use `createVueRender` instead.*/
|
|
11
12
|
declare const defineVueRender: ({ onCreatedApp, }?: CreateVueRenderOptions) => _web_widget_schema.ClientRender<Component, unknown, _web_widget_schema.ClientRenderOptions, void | _web_widget_schema.ClientRenderResult<unknown>>;
|
|
12
13
|
declare const render: _web_widget_schema.ClientRender<Component, unknown, _web_widget_schema.ClientRenderOptions, void | _web_widget_schema.ClientRenderResult<unknown>>;
|
|
13
14
|
|
|
14
|
-
export { createVueRender, defineVueRender, render };
|
|
15
|
+
export { VueWidgetFactory, createVueRender, defineVueRender, render, widget };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
createWidgetAdapter,
|
|
3
3
|
installErrorHandler,
|
|
4
4
|
resolveFallback
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-ER6EL6Y7.js";
|
|
6
6
|
import {
|
|
7
7
|
asReactWidget,
|
|
8
8
|
toReact
|
|
@@ -11,22 +11,23 @@ import {
|
|
|
11
11
|
// src/adapter.client.ts
|
|
12
12
|
import { defineClientRender } from "@web-widget/helpers";
|
|
13
13
|
import { Suspense, createApp, createSSRApp, h } from "vue";
|
|
14
|
+
var widget = createWidgetAdapter();
|
|
14
15
|
var createWidgetSuspense = (component) => (props) => h(Suspense, null, [h(component, props)]);
|
|
15
16
|
var createVueRender = ({
|
|
16
17
|
onCreatedApp = async () => {
|
|
17
18
|
}
|
|
18
19
|
} = {}) => {
|
|
19
20
|
return defineClientRender(
|
|
20
|
-
async (component, data, { recovering, container
|
|
21
|
+
async (component, data, { recovering, container }) => {
|
|
21
22
|
data = data != null ? data : {};
|
|
22
23
|
if (!component) {
|
|
23
24
|
throw new TypeError(`Missing component.`);
|
|
24
25
|
}
|
|
25
|
-
if (!
|
|
26
|
+
if (!container) {
|
|
26
27
|
throw new Error(`Missing container.`);
|
|
27
28
|
}
|
|
28
29
|
let app;
|
|
29
|
-
const context = { data, recovering, container
|
|
30
|
+
const context = { data, recovering, container };
|
|
30
31
|
const WidgetSuspense = createWidgetSuspense(component);
|
|
31
32
|
return {
|
|
32
33
|
async mount() {
|
|
@@ -36,7 +37,7 @@ var createVueRender = ({
|
|
|
36
37
|
error = err;
|
|
37
38
|
});
|
|
38
39
|
await onCreatedApp(app, context, component, data);
|
|
39
|
-
app.mount(
|
|
40
|
+
app.mount(container);
|
|
40
41
|
if (error) {
|
|
41
42
|
throw error;
|
|
42
43
|
}
|
|
@@ -53,10 +54,10 @@ var defineVueRender = createVueRender;
|
|
|
53
54
|
var render = createVueRender();
|
|
54
55
|
export {
|
|
55
56
|
asReactWidget,
|
|
56
|
-
container,
|
|
57
57
|
createVueRender,
|
|
58
58
|
defineVueRender,
|
|
59
59
|
render,
|
|
60
60
|
resolveFallback,
|
|
61
|
-
toReact
|
|
61
|
+
toReact,
|
|
62
|
+
widget
|
|
62
63
|
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as _web_widget_schema from '@web-widget/schema';
|
|
2
|
+
export { WidgetContainerOptions } from '@web-widget/schema';
|
|
3
|
+
import { C as CreateVueRenderOptions, V as VueWidgetFactory } from './types-Q7wIvDbF.js';
|
|
4
|
+
export { a as VueWidgetComponent, b as VueWidgetContainerProps, r as resolveFallback } from './types-Q7wIvDbF.js';
|
|
2
5
|
import { Component } from 'vue';
|
|
3
6
|
import { SSRContext } from 'vue/server-renderer';
|
|
4
|
-
import { C as CreateVueRenderOptions } from './types-BY8s0m9C.js';
|
|
5
|
-
export { D as DefineWebWidgetOptions, V as VueWidgetComponent, W as WidgetContainerConfig, a as WidgetFallback, c as container, r as resolveFallback } from './types-BY8s0m9C.js';
|
|
6
7
|
export { asReactWidget, toReact } from './vue.js';
|
|
7
|
-
import '@web-widget/web-widget';
|
|
8
8
|
import '@web-widget/react/adapter';
|
|
9
9
|
|
|
10
10
|
declare module '@web-widget/schema' {
|
|
@@ -13,6 +13,7 @@ declare module '@web-widget/schema' {
|
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
declare const widget: VueWidgetFactory;
|
|
16
17
|
interface VueRenderOptions {
|
|
17
18
|
vue?: SSRContext;
|
|
18
19
|
}
|
|
@@ -21,4 +22,4 @@ declare const createVueRender: ({ onCreatedApp, }?: CreateVueRenderOptions) => _
|
|
|
21
22
|
declare const defineVueRender: ({ onCreatedApp, }?: CreateVueRenderOptions) => _web_widget_schema.ServerRender<Component, unknown, _web_widget_schema.ServerRenderOptions, _web_widget_schema.ServerRenderResult>;
|
|
22
23
|
declare const render: _web_widget_schema.ServerRender<Component, unknown, _web_widget_schema.ServerRenderOptions, _web_widget_schema.ServerRenderResult>;
|
|
23
24
|
|
|
24
|
-
export { type VueRenderOptions, createVueRender, defineVueRender, render };
|
|
25
|
+
export { type VueRenderOptions, VueWidgetFactory, createVueRender, defineVueRender, render, widget };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
createWidgetAdapter,
|
|
3
3
|
installErrorHandler,
|
|
4
4
|
resolveFallback
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-ER6EL6Y7.js";
|
|
6
6
|
import {
|
|
7
7
|
asReactWidget,
|
|
8
8
|
toReact
|
|
@@ -13,8 +13,25 @@ import { defineServerRender } from "@web-widget/helpers";
|
|
|
13
13
|
import { createSSRApp, h, Suspense } from "vue";
|
|
14
14
|
import {
|
|
15
15
|
renderToString,
|
|
16
|
-
renderToWebStream
|
|
16
|
+
renderToWebStream,
|
|
17
|
+
ssrRenderVNode
|
|
17
18
|
} from "vue/server-renderer";
|
|
19
|
+
async function resolveSSRBuffer(value) {
|
|
20
|
+
const resolved = await value;
|
|
21
|
+
if (Array.isArray(resolved)) {
|
|
22
|
+
let html = "";
|
|
23
|
+
for (const item of resolved) html += await resolveSSRBuffer(item);
|
|
24
|
+
return html;
|
|
25
|
+
}
|
|
26
|
+
return typeof resolved === "string" ? resolved : "";
|
|
27
|
+
}
|
|
28
|
+
var widget = createWidgetAdapter(async (nodes, parent) => {
|
|
29
|
+
const buffer = [];
|
|
30
|
+
for (const node of nodes) {
|
|
31
|
+
ssrRenderVNode((item) => buffer.push(item), node, parent);
|
|
32
|
+
}
|
|
33
|
+
return resolveSSRBuffer(buffer);
|
|
34
|
+
});
|
|
18
35
|
var createWidgetSuspense = (component) => (props) => h(Suspense, null, [h(component, props)]);
|
|
19
36
|
var createVueRender = ({
|
|
20
37
|
onCreatedApp = async () => {
|
|
@@ -37,8 +54,8 @@ var createVueRender = ({
|
|
|
37
54
|
});
|
|
38
55
|
await onCreatedApp(app, context, component, data);
|
|
39
56
|
if (progressive) {
|
|
40
|
-
const
|
|
41
|
-
const reader =
|
|
57
|
+
const byteStream = renderToWebStream(app, ssrContext);
|
|
58
|
+
const reader = byteStream.getReader();
|
|
42
59
|
const first = await reader.read();
|
|
43
60
|
try {
|
|
44
61
|
if (ssrContext == null ? void 0 : ssrContext.teleports) {
|
|
@@ -99,10 +116,10 @@ var defineVueRender = createVueRender;
|
|
|
99
116
|
var render = createVueRender();
|
|
100
117
|
export {
|
|
101
118
|
asReactWidget,
|
|
102
|
-
container,
|
|
103
119
|
createVueRender,
|
|
104
120
|
defineVueRender,
|
|
105
121
|
render,
|
|
106
122
|
resolveFallback,
|
|
107
|
-
toReact
|
|
123
|
+
toReact,
|
|
124
|
+
widget
|
|
108
125
|
};
|
package/dist/vue.d.ts
CHANGED
|
@@ -4,15 +4,15 @@ import { ReactWidgetComponent } from '@web-widget/react/adapter';
|
|
|
4
4
|
/**
|
|
5
5
|
* Adapt Vue component types to React widget component types.
|
|
6
6
|
*
|
|
7
|
-
* @deprecated Use `
|
|
7
|
+
* @deprecated Use `widget()` from `@web-widget/react/adapter` instead.
|
|
8
8
|
* The build tool automatically infers props types for both static imports
|
|
9
|
-
* and explicit `
|
|
9
|
+
* and explicit `widget(() => import(...))` calls.
|
|
10
10
|
*
|
|
11
11
|
* This is a type-level cast only — the actual cross-framework rendering
|
|
12
12
|
* is handled by the `@widget` system.
|
|
13
13
|
*/
|
|
14
14
|
declare function asReactWidget<T>(component: Component<T>): ReactWidgetComponent<Omit<T, keyof ComponentPublicInstance | "$route" | "$router">>;
|
|
15
|
-
/** @deprecated Use `
|
|
15
|
+
/** @deprecated Use `widget()` from `@web-widget/react/adapter` instead. */
|
|
16
16
|
declare const toReact: typeof asReactWidget;
|
|
17
17
|
|
|
18
18
|
export { asReactWidget, toReact };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// src/transform.ts
|
|
2
|
+
var transform_default = {
|
|
3
|
+
name: "vue",
|
|
4
|
+
extensions: [".vue"],
|
|
5
|
+
adapter: "@web-widget/vue/adapter",
|
|
6
|
+
deriveExports: [
|
|
7
|
+
{ name: "handler", default: "{GET({html}){return html()}}" },
|
|
8
|
+
{ name: "meta", default: "{}" }
|
|
9
|
+
]
|
|
10
|
+
};
|
|
11
|
+
export {
|
|
12
|
+
transform_default as default
|
|
13
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@web-widget/vue",
|
|
3
3
|
"description": "Vue adapter",
|
|
4
|
-
"version": "3.0.0-beta.
|
|
4
|
+
"version": "3.0.0-beta.5",
|
|
5
5
|
"homepage": "https://github.com/web-widget/web-widget#readme",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -13,54 +13,47 @@
|
|
|
13
13
|
},
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@web-widget/helpers": "
|
|
17
|
-
"@web-widget/
|
|
18
|
-
"@web-widget/
|
|
19
|
-
"@web-widget/react": "
|
|
16
|
+
"@web-widget/helpers": "workspace:*",
|
|
17
|
+
"@web-widget/web-widget": "workspace:*",
|
|
18
|
+
"@web-widget/schema": "workspace:*",
|
|
19
|
+
"@web-widget/react": "workspace:*"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
|
-
"
|
|
23
|
-
"
|
|
22
|
+
"happy-dom": "14.12.3",
|
|
23
|
+
"tsup": "catalog:",
|
|
24
|
+
"typescript": "catalog:",
|
|
25
|
+
"vitest": "catalog:",
|
|
24
26
|
"vue": "^3.5.34"
|
|
25
27
|
},
|
|
26
28
|
"exports": {
|
|
27
29
|
".": {
|
|
28
30
|
"types": "./dist/vue.d.ts",
|
|
31
|
+
"development": "./src/index.ts",
|
|
29
32
|
"default": "./dist/vue.js"
|
|
30
33
|
},
|
|
34
|
+
"./transform": {
|
|
35
|
+
"types": "./dist/vue.transform.d.ts",
|
|
36
|
+
"development": "./src/transform.ts",
|
|
37
|
+
"default": "./dist/vue.transform.js"
|
|
38
|
+
},
|
|
31
39
|
"./adapter": {
|
|
32
40
|
"worker": {
|
|
33
41
|
"types": "./dist/vue.adapter.server.d.ts",
|
|
42
|
+
"development": "./src/adapter.server.ts",
|
|
34
43
|
"default": "./dist/vue.adapter.server.js"
|
|
35
44
|
},
|
|
36
45
|
"browser": {
|
|
37
46
|
"types": "./dist/vue.adapter.client.d.ts",
|
|
47
|
+
"development": "./src/adapter.client.ts",
|
|
38
48
|
"default": "./dist/vue.adapter.client.js"
|
|
39
49
|
},
|
|
40
50
|
"default": {
|
|
41
51
|
"types": "./dist/vue.adapter.server.d.ts",
|
|
52
|
+
"development": "./src/adapter.server.ts",
|
|
42
53
|
"default": "./dist/vue.adapter.server.js"
|
|
43
54
|
}
|
|
44
55
|
}
|
|
45
56
|
},
|
|
46
|
-
"webWidgetAdapter": {
|
|
47
|
-
"version": "1.0.0",
|
|
48
|
-
"name": "vue",
|
|
49
|
-
"extensions": [
|
|
50
|
-
".vue"
|
|
51
|
-
],
|
|
52
|
-
"adapter": "./adapter",
|
|
53
|
-
"deriveExports": [
|
|
54
|
-
{
|
|
55
|
-
"name": "handler",
|
|
56
|
-
"default": "{GET({html}){return html()}}"
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
"name": "meta",
|
|
60
|
-
"default": "{}"
|
|
61
|
-
}
|
|
62
|
-
]
|
|
63
|
-
},
|
|
64
57
|
"files": [
|
|
65
58
|
"dist"
|
|
66
59
|
],
|
|
@@ -68,16 +61,41 @@
|
|
|
68
61
|
"vue": ">3.3.3"
|
|
69
62
|
},
|
|
70
63
|
"publishConfig": {
|
|
71
|
-
"access": "public"
|
|
64
|
+
"access": "public",
|
|
65
|
+
"exports": {
|
|
66
|
+
".": {
|
|
67
|
+
"types": "./dist/vue.d.ts",
|
|
68
|
+
"default": "./dist/vue.js"
|
|
69
|
+
},
|
|
70
|
+
"./transform": {
|
|
71
|
+
"types": "./dist/vue.transform.d.ts",
|
|
72
|
+
"default": "./dist/vue.transform.js"
|
|
73
|
+
},
|
|
74
|
+
"./adapter": {
|
|
75
|
+
"worker": {
|
|
76
|
+
"types": "./dist/vue.adapter.server.d.ts",
|
|
77
|
+
"default": "./dist/vue.adapter.server.js"
|
|
78
|
+
},
|
|
79
|
+
"browser": {
|
|
80
|
+
"types": "./dist/vue.adapter.client.d.ts",
|
|
81
|
+
"default": "./dist/vue.adapter.client.js"
|
|
82
|
+
},
|
|
83
|
+
"default": {
|
|
84
|
+
"types": "./dist/vue.adapter.server.d.ts",
|
|
85
|
+
"default": "./dist/vue.adapter.server.js"
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
72
89
|
},
|
|
73
|
-
"sideEffects": false,
|
|
74
|
-
"type": "module",
|
|
75
90
|
"scripts": {
|
|
76
91
|
"build": "pnpm exec tsup",
|
|
77
92
|
"clean:build": "rm -rf dist",
|
|
78
93
|
"clean:node": "rm -rf node_modules",
|
|
79
94
|
"dev": "pnpm exec tsup --watch",
|
|
80
95
|
"lint": "eslint src",
|
|
81
|
-
"prebuild": "pnpm run clean:build"
|
|
82
|
-
|
|
83
|
-
}
|
|
96
|
+
"prebuild": "pnpm run clean:build",
|
|
97
|
+
"test": "vitest run"
|
|
98
|
+
},
|
|
99
|
+
"sideEffects": false,
|
|
100
|
+
"type": "module"
|
|
101
|
+
}
|
package/dist/chunk-7KXT6LS2.js
DELETED
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
// src/error-handler.ts
|
|
2
|
-
import { cacheProviderIsLoading } from "@web-widget/helpers/cache";
|
|
3
|
-
function installErrorHandler(app, callback, throwUnhandledErrorInProduction = false) {
|
|
4
|
-
app.config.throwUnhandledErrorInProduction = throwUnhandledErrorInProduction;
|
|
5
|
-
app.config.errorHandler = (err, instance, info) => {
|
|
6
|
-
if (cacheProviderIsLoading(err)) {
|
|
7
|
-
return;
|
|
8
|
-
}
|
|
9
|
-
app.config.warnHandler = () => {
|
|
10
|
-
};
|
|
11
|
-
callback(err);
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
// src/components.ts
|
|
16
|
-
import { WebWidgetRenderer } from "@web-widget/web-widget";
|
|
17
|
-
import {
|
|
18
|
-
h,
|
|
19
|
-
defineComponent,
|
|
20
|
-
Suspense,
|
|
21
|
-
useAttrs,
|
|
22
|
-
ref,
|
|
23
|
-
onErrorCaptured
|
|
24
|
-
} from "vue";
|
|
25
|
-
import { IS_CLIENT } from "@web-widget/helpers/env";
|
|
26
|
-
var WebWidget = /* @__PURE__ */ defineComponent({
|
|
27
|
-
name: "WebWidgetRoot",
|
|
28
|
-
props: {
|
|
29
|
-
base: {
|
|
30
|
-
type: String
|
|
31
|
-
},
|
|
32
|
-
data: {
|
|
33
|
-
type: Object,
|
|
34
|
-
default: () => ({})
|
|
35
|
-
},
|
|
36
|
-
errorFallback: {
|
|
37
|
-
type: Object,
|
|
38
|
-
default: null
|
|
39
|
-
},
|
|
40
|
-
import: {
|
|
41
|
-
type: String
|
|
42
|
-
},
|
|
43
|
-
inactive: {
|
|
44
|
-
type: Boolean,
|
|
45
|
-
default: false
|
|
46
|
-
},
|
|
47
|
-
loader: {
|
|
48
|
-
type: Function,
|
|
49
|
-
required: true
|
|
50
|
-
},
|
|
51
|
-
loading: {
|
|
52
|
-
type: String
|
|
53
|
-
},
|
|
54
|
-
meta: {
|
|
55
|
-
type: Object
|
|
56
|
-
},
|
|
57
|
-
name: {
|
|
58
|
-
type: String
|
|
59
|
-
},
|
|
60
|
-
renderStage: {
|
|
61
|
-
type: String
|
|
62
|
-
},
|
|
63
|
-
renderTarget: {
|
|
64
|
-
type: String,
|
|
65
|
-
default: "light"
|
|
66
|
-
}
|
|
67
|
-
},
|
|
68
|
-
async setup({ loader, errorFallback, ...props }, { slots }) {
|
|
69
|
-
if (!loader) {
|
|
70
|
-
throw new TypeError(`Missing loader.`);
|
|
71
|
-
}
|
|
72
|
-
if (Object.keys(slots).length > 0) {
|
|
73
|
-
throw new TypeError(`Slot not supported.`);
|
|
74
|
-
}
|
|
75
|
-
const widget = new WebWidgetRenderer(loader, {
|
|
76
|
-
...props,
|
|
77
|
-
children: ""
|
|
78
|
-
});
|
|
79
|
-
const tag = widget.localName;
|
|
80
|
-
const attrs = widget.attributes;
|
|
81
|
-
const innerHTML = await widget.renderInnerHTMLToString().catch((err) => {
|
|
82
|
-
const error = err instanceof Error ? err : new Error(String(err));
|
|
83
|
-
console.error("[VueWidget] Rendering error:", error);
|
|
84
|
-
return error;
|
|
85
|
-
});
|
|
86
|
-
if (innerHTML instanceof Error) {
|
|
87
|
-
return () => errorFallback;
|
|
88
|
-
}
|
|
89
|
-
if (IS_CLIENT) {
|
|
90
|
-
await customElements.whenDefined(tag);
|
|
91
|
-
}
|
|
92
|
-
const data = attrs.data;
|
|
93
|
-
delete attrs.data;
|
|
94
|
-
return () => {
|
|
95
|
-
const nodeProps = {
|
|
96
|
-
...attrs,
|
|
97
|
-
...IS_CLIENT ? { "^data": data } : { data },
|
|
98
|
-
...!IS_CLIENT ? { innerHTML } : null
|
|
99
|
-
};
|
|
100
|
-
return h(tag, nodeProps);
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
function resolveFallback(fallback) {
|
|
105
|
-
var _a;
|
|
106
|
-
if (fallback !== null && typeof fallback === "object" && !("__v_isVNode" in fallback) && ("pending" in fallback || "error" in fallback)) {
|
|
107
|
-
const obj = fallback;
|
|
108
|
-
return {
|
|
109
|
-
pendingFallback: obj.pending,
|
|
110
|
-
errorFallback: (_a = obj.error) != null ? _a : obj.pending
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
return {
|
|
114
|
-
pendingFallback: fallback,
|
|
115
|
-
errorFallback: fallback
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
function container(loader, options = {}) {
|
|
119
|
-
return defineComponent({
|
|
120
|
-
name: "VueWidget",
|
|
121
|
-
inheritAttrs: false,
|
|
122
|
-
props: {
|
|
123
|
-
widget: {
|
|
124
|
-
type: Object,
|
|
125
|
-
default: () => ({})
|
|
126
|
-
}
|
|
127
|
-
},
|
|
128
|
-
setup({ widget }, { slots }) {
|
|
129
|
-
var _a;
|
|
130
|
-
const {
|
|
131
|
-
fallback,
|
|
132
|
-
loading = (_a = options.loading) != null ? _a : "lazy",
|
|
133
|
-
serverOnly,
|
|
134
|
-
clientOnly
|
|
135
|
-
} = widget;
|
|
136
|
-
const { pendingFallback, errorFallback } = resolveFallback(fallback);
|
|
137
|
-
const renderStage = serverOnly ? "server" : clientOnly ? "client" : options.renderStage;
|
|
138
|
-
const data = useAttrs();
|
|
139
|
-
const error = ref(null);
|
|
140
|
-
onErrorCaptured((err) => {
|
|
141
|
-
error.value = err;
|
|
142
|
-
return false;
|
|
143
|
-
});
|
|
144
|
-
return () => {
|
|
145
|
-
var _a2;
|
|
146
|
-
if (error.value && errorFallback) {
|
|
147
|
-
return errorFallback;
|
|
148
|
-
}
|
|
149
|
-
return h(
|
|
150
|
-
Suspense,
|
|
151
|
-
{},
|
|
152
|
-
{
|
|
153
|
-
default: h(
|
|
154
|
-
WebWidget,
|
|
155
|
-
{
|
|
156
|
-
...options,
|
|
157
|
-
data,
|
|
158
|
-
errorFallback,
|
|
159
|
-
loader,
|
|
160
|
-
loading,
|
|
161
|
-
renderStage,
|
|
162
|
-
renderTarget: (_a2 = options.renderTarget) != null ? _a2 : "light"
|
|
163
|
-
},
|
|
164
|
-
slots
|
|
165
|
-
),
|
|
166
|
-
fallback: pendingFallback
|
|
167
|
-
}
|
|
168
|
-
);
|
|
169
|
-
};
|
|
170
|
-
}
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
export {
|
|
175
|
-
installErrorHandler,
|
|
176
|
-
resolveFallback,
|
|
177
|
-
container
|
|
178
|
-
};
|
package/dist/types-BY8s0m9C.d.ts
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import { WebWidgetRendererOptions, Loader } from '@web-widget/web-widget';
|
|
2
|
-
import { ExtractWidgetProps } from '@web-widget/schema';
|
|
3
|
-
import { DefineComponent, VNode, App, Component } from 'vue';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* A Vue component wrapping a widget, with props `T` plus container config.
|
|
7
|
-
*/
|
|
8
|
-
type VueWidgetComponent<T = unknown> = DefineComponent<T & {
|
|
9
|
-
widget?: WidgetContainerConfig;
|
|
10
|
-
}>;
|
|
11
|
-
interface DefineWebWidgetOptions {
|
|
12
|
-
base?: WebWidgetRendererOptions['base'];
|
|
13
|
-
import?: WebWidgetRendererOptions['import'];
|
|
14
|
-
loading?: WebWidgetRendererOptions['loading'];
|
|
15
|
-
name?: WebWidgetRendererOptions['name'];
|
|
16
|
-
renderStage?: WebWidgetRendererOptions['renderStage'];
|
|
17
|
-
renderTarget?: WebWidgetRendererOptions['renderTarget'];
|
|
18
|
-
}
|
|
19
|
-
type WidgetFallback = VNode | {
|
|
20
|
-
pending?: VNode;
|
|
21
|
-
error?: VNode;
|
|
22
|
-
};
|
|
23
|
-
/**
|
|
24
|
-
* Resolve a WidgetFallback into separate pending and error VNodes.
|
|
25
|
-
* - `VNode` — used for both pending and error.
|
|
26
|
-
* - `{ pending?, error? }` — specify independently; `error` defaults to `pending`.
|
|
27
|
-
*/
|
|
28
|
-
declare function resolveFallback(fallback: WidgetFallback | undefined): {
|
|
29
|
-
pendingFallback: VNode;
|
|
30
|
-
errorFallback: VNode;
|
|
31
|
-
};
|
|
32
|
-
interface WidgetContainerConfig {
|
|
33
|
-
/**
|
|
34
|
-
* Fallback UI for loading and error states.
|
|
35
|
-
*
|
|
36
|
-
* Only effective during server-side rendering: loading UI shows while the
|
|
37
|
-
* widget module renders; error UI shows if rendering fails. Both are
|
|
38
|
-
* serialized into the HTML stream — no client-side retry exists in the
|
|
39
|
-
* islands architecture.
|
|
40
|
-
*
|
|
41
|
-
* - `VNode` — used for both pending (Suspense) and error.
|
|
42
|
-
* - `{ pending?, error? }` — specify independently; `error` defaults to `pending`.
|
|
43
|
-
*
|
|
44
|
-
* @example
|
|
45
|
-
* // Simple: same UI for both states
|
|
46
|
-
* <Widget :widget="{ fallback: h(Spinner) }" />
|
|
47
|
-
*
|
|
48
|
-
* // Differentiated: separate pending and error UI
|
|
49
|
-
* <Widget :widget="{ fallback: { pending: h(Spinner), error: h(ErrorUI) } }" />
|
|
50
|
-
*/
|
|
51
|
-
fallback?: WidgetFallback;
|
|
52
|
-
/** Client-side module loading strategy: `'lazy'` loads on first render, `'eager'` on module parse, `'idle'` on browser idle. */
|
|
53
|
-
loading?: WebWidgetRendererOptions['loading'];
|
|
54
|
-
/** Widget renders only on the server (SSR), producing static HTML with no client-side mount. Mutually exclusive with `clientOnly`. */
|
|
55
|
-
serverOnly?: true;
|
|
56
|
-
/** Widget renders only on the client, producing no server HTML (empty placeholder until client mount). Mutually exclusive with `serverOnly`. */
|
|
57
|
-
clientOnly?: true;
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Container function (WebWidgetAdapter protocol).
|
|
61
|
-
*
|
|
62
|
-
* Wraps a widget module loader into a Vue component with props type
|
|
63
|
-
* inference from the source module's default export.
|
|
64
|
-
*
|
|
65
|
-
* @example
|
|
66
|
-
* ```ts
|
|
67
|
-
* import { container } from '@web-widget/vue/adapter';
|
|
68
|
-
*
|
|
69
|
-
* const Counter = container(() => import('./Counter@widget.vue'));
|
|
70
|
-
* // ^? VueWidgetComponent<{ count: number }>
|
|
71
|
-
* ```
|
|
72
|
-
*/
|
|
73
|
-
declare function container<M>(loader: () => Promise<M>, options?: DefineWebWidgetOptions): VueWidgetComponent<ExtractWidgetProps<M>>;
|
|
74
|
-
declare function container<Props>(loader: Loader, options?: DefineWebWidgetOptions): VueWidgetComponent<Props>;
|
|
75
|
-
|
|
76
|
-
interface CreateVueRenderOptions {
|
|
77
|
-
onCreatedApp?: (app: App<Element>, context: {
|
|
78
|
-
container?: Element | DocumentFragment;
|
|
79
|
-
data: any;
|
|
80
|
-
progressive?: boolean;
|
|
81
|
-
recovering?: boolean;
|
|
82
|
-
}, component: Component, props: any) => Promise<void>;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export { type CreateVueRenderOptions as C, type DefineWebWidgetOptions as D, type VueWidgetComponent as V, type WidgetContainerConfig as W, type WidgetFallback as a, container as c, resolveFallback as r };
|