dynim-vue 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/dist/DynimProvider.d.ts +87 -0
- package/dist/DynimProvider.d.ts.map +1 -0
- package/dist/DynimProvider.js +385 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/inference/sharedContext.d.ts +38 -0
- package/dist/inference/sharedContext.d.ts.map +1 -0
- package/dist/inference/sharedContext.js +75 -0
- package/dist/inference/types.d.ts +16 -0
- package/dist/inference/types.d.ts.map +1 -0
- package/dist/inference/types.js +1 -0
- package/dist/theme.d.ts +58 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +97 -0
- package/dist/useDynim.d.ts +5 -0
- package/dist/useDynim.d.ts.map +1 -0
- package/dist/useDynim.js +4 -0
- package/dist/vite/index.d.ts +5 -0
- package/dist/vite/index.d.ts.map +1 -0
- package/dist/vite/index.js +4 -0
- package/dist/vite/plugin.d.ts +54 -0
- package/dist/vite/plugin.d.ts.map +1 -0
- package/dist/vite/plugin.js +82 -0
- package/package.json +47 -0
- package/src/vite/virtual-module.d.ts +24 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DynimProvider - Single provider for all Dynim functionality (Vue)
|
|
3
|
+
*
|
|
4
|
+
* Handles:
|
|
5
|
+
* - Loading tenant bundles
|
|
6
|
+
* - Visual builder UI (when user has edit permissions)
|
|
7
|
+
* - Shared context for bundles to access Vue, packages, etc.
|
|
8
|
+
*/
|
|
9
|
+
import { type InjectionKey, type PropType } from 'vue';
|
|
10
|
+
import * as Vue from 'vue';
|
|
11
|
+
import type { CodeMessage } from 'dynim-core';
|
|
12
|
+
export interface DynimConfig {
|
|
13
|
+
/** Function to fetch a session token for authentication */
|
|
14
|
+
getSession?: () => Promise<{
|
|
15
|
+
token: string;
|
|
16
|
+
refreshToken?: string;
|
|
17
|
+
}>;
|
|
18
|
+
/** Called when an error occurs */
|
|
19
|
+
onError?: (error: Event | Error) => void;
|
|
20
|
+
/** NPM packages to expose to bundles (e.g., { 'vue-router': VueRouter }) */
|
|
21
|
+
packages?: Record<string, unknown>;
|
|
22
|
+
/** Custom composables/hooks to expose to bundles */
|
|
23
|
+
hooks?: Record<string, unknown>;
|
|
24
|
+
/** Vue contexts (provide/inject values) to expose to bundles */
|
|
25
|
+
contexts?: Record<string, unknown>;
|
|
26
|
+
}
|
|
27
|
+
export interface DynimContextValue {
|
|
28
|
+
/** Enter edit mode (shows builder UI) */
|
|
29
|
+
enterBuilder: () => void;
|
|
30
|
+
/** Exit edit mode */
|
|
31
|
+
exitBuilder: () => void;
|
|
32
|
+
/** Whether builder/edit mode is active */
|
|
33
|
+
isEditing: boolean;
|
|
34
|
+
/** Send a code edit request to AI */
|
|
35
|
+
sendCode: (query: string) => Promise<void>;
|
|
36
|
+
/** Save current edits */
|
|
37
|
+
saveCode: () => Promise<void>;
|
|
38
|
+
/** Abandon/discard current edits */
|
|
39
|
+
abandonCode: () => Promise<void>;
|
|
40
|
+
/** Current code message state (thinking, edits, etc.) */
|
|
41
|
+
codeMessage: CodeMessage;
|
|
42
|
+
/** Whether a bundle is currently loaded */
|
|
43
|
+
isBundleLoaded: boolean;
|
|
44
|
+
/** Whether bundle is loading */
|
|
45
|
+
isBundleLoading: boolean;
|
|
46
|
+
}
|
|
47
|
+
export declare const DynimInjectionKey: InjectionKey<DynimContextValue>;
|
|
48
|
+
/**
|
|
49
|
+
* DynimProvider - Wrap your app with this to enable Dynim functionality
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```vue
|
|
53
|
+
* <script setup>
|
|
54
|
+
* import { DynimProvider } from 'dynim-vue';
|
|
55
|
+
* </script>
|
|
56
|
+
*
|
|
57
|
+
* <template>
|
|
58
|
+
* <DynimProvider>
|
|
59
|
+
* <App />
|
|
60
|
+
* </DynimProvider>
|
|
61
|
+
* </template>
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export declare const DynimProvider: Vue.DefineComponent<Vue.ExtractPropTypes<{
|
|
65
|
+
config: {
|
|
66
|
+
type: PropType<DynimConfig>;
|
|
67
|
+
default: () => {};
|
|
68
|
+
};
|
|
69
|
+
}>, () => (Vue.VNode<Vue.RendererNode, Vue.RendererElement, {
|
|
70
|
+
[key: string]: any;
|
|
71
|
+
}> | (Vue.VNode<Vue.RendererNode, Vue.RendererElement, {
|
|
72
|
+
[key: string]: any;
|
|
73
|
+
}> | Vue.VNode<Vue.RendererNode, Vue.RendererElement, {
|
|
74
|
+
[key: string]: any;
|
|
75
|
+
}>[] | undefined)[] | null | undefined)[], {}, {}, {}, Vue.ComponentOptionsMixin, Vue.ComponentOptionsMixin, {}, string, Vue.PublicProps, Readonly<Vue.ExtractPropTypes<{
|
|
76
|
+
config: {
|
|
77
|
+
type: PropType<DynimConfig>;
|
|
78
|
+
default: () => {};
|
|
79
|
+
};
|
|
80
|
+
}>> & Readonly<{}>, {
|
|
81
|
+
config: DynimConfig;
|
|
82
|
+
}, {}, {}, {}, string, Vue.ComponentProvideOptions, true, {}, any>;
|
|
83
|
+
/**
|
|
84
|
+
* Composable to access Dynim functionality
|
|
85
|
+
*/
|
|
86
|
+
export declare function useDynim(): DynimContextValue;
|
|
87
|
+
//# sourceMappingURL=DynimProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DynimProvider.d.ts","sourceRoot":"","sources":["../src/DynimProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAWL,KAAK,YAAY,EACjB,KAAK,QAAQ,EAEd,MAAM,KAAK,CAAC;AACb,OAAO,KAAK,GAAG,MAAM,KAAK,CAAC;AAS3B,OAAO,KAAK,EAIV,WAAW,EAEZ,MAAM,YAAY,CAAC;AAIpB,MAAM,WAAW,WAAW;IAC1B,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrE,kCAAkC;IAClC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,KAAK,IAAI,CAAC;IACzC,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,oDAAoD;IACpD,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,iBAAiB;IAChC,yCAAyC;IACzC,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,qBAAqB;IACrB,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,0CAA0C;IAC1C,SAAS,EAAE,OAAO,CAAC;IACnB,qCAAqC;IACrC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,yBAAyB;IACzB,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,oCAAoC;IACpC,WAAW,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,yDAAyD;IACzD,WAAW,EAAE,WAAW,CAAC;IACzB,2CAA2C;IAC3C,cAAc,EAAE,OAAO,CAAC;IACxB,gCAAgC;IAChC,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,eAAO,MAAM,iBAAiB,EAAE,YAAY,CAAC,iBAAiB,CAAmB,CAAC;AAElF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,aAAa;;cAIJ,QAAQ,CAAC,WAAW,CAAC;;;;;;;;;;;cAArB,QAAQ,CAAC,WAAW,CAAC;;;;;kEA4XzC,CAAC;AAEH;;GAEG;AACH,wBAAgB,QAAQ,IAAI,iBAAiB,CAM5C"}
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DynimProvider - Single provider for all Dynim functionality (Vue)
|
|
3
|
+
*
|
|
4
|
+
* Handles:
|
|
5
|
+
* - Loading tenant bundles
|
|
6
|
+
* - Visual builder UI (when user has edit permissions)
|
|
7
|
+
* - Shared context for bundles to access Vue, packages, etc.
|
|
8
|
+
*/
|
|
9
|
+
import { defineComponent, ref, reactive, computed, provide, inject, onMounted, onUnmounted, watch, h, } from 'vue';
|
|
10
|
+
import * as Vue from 'vue';
|
|
11
|
+
import { createBuilderClient, createBuilder, createCodeClient, createBundleLoader, BundleNotFoundError, BundleAuthError, } from 'dynim-core';
|
|
12
|
+
import { createSharedContext, updateSharedContext, isSharedContextReady } from './inference/sharedContext';
|
|
13
|
+
import { generateThemeCSS } from './theme';
|
|
14
|
+
export const DynimInjectionKey = Symbol('dynim');
|
|
15
|
+
/**
|
|
16
|
+
* DynimProvider - Wrap your app with this to enable Dynim functionality
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```vue
|
|
20
|
+
* <script setup>
|
|
21
|
+
* import { DynimProvider } from 'dynim-vue';
|
|
22
|
+
* </script>
|
|
23
|
+
*
|
|
24
|
+
* <template>
|
|
25
|
+
* <DynimProvider>
|
|
26
|
+
* <App />
|
|
27
|
+
* </DynimProvider>
|
|
28
|
+
* </template>
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export const DynimProvider = defineComponent({
|
|
32
|
+
name: 'DynimProvider',
|
|
33
|
+
props: {
|
|
34
|
+
config: {
|
|
35
|
+
type: Object,
|
|
36
|
+
default: () => ({}),
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
setup(props, { slots }) {
|
|
40
|
+
// Client refs (non-reactive - plain variables)
|
|
41
|
+
let builderClientRef = null;
|
|
42
|
+
let builderRef = null;
|
|
43
|
+
let codeClientRef = null;
|
|
44
|
+
let bundleLoaderRef = null;
|
|
45
|
+
// Track when we're exiting to prevent auto-load from re-triggering
|
|
46
|
+
let isExitingRef = false;
|
|
47
|
+
let hasAttemptedInitialLoadRef = false;
|
|
48
|
+
let isBuilderActiveRef = false;
|
|
49
|
+
// Cached auth token
|
|
50
|
+
let cachedTokenRef = null;
|
|
51
|
+
let tokenPromiseRef = null;
|
|
52
|
+
// Bundle load signal
|
|
53
|
+
let pendingBundleProjectIdRef = null;
|
|
54
|
+
// Theme state ref
|
|
55
|
+
let hasAttemptedThemeLoadRef = false;
|
|
56
|
+
// Load bundle function ref
|
|
57
|
+
let loadBundleRef = null;
|
|
58
|
+
// Reactive state
|
|
59
|
+
const isEditing = ref(false);
|
|
60
|
+
const isBundleLoaded = ref(false);
|
|
61
|
+
const isBundleLoading = ref(false);
|
|
62
|
+
const isInitialLoadComplete = ref(false);
|
|
63
|
+
const TenantApp = ref(null);
|
|
64
|
+
const bundleError = ref(null);
|
|
65
|
+
const bundleLoadSignal = ref(0);
|
|
66
|
+
const theme = ref(null);
|
|
67
|
+
const codeMessage = reactive({
|
|
68
|
+
thinking: '',
|
|
69
|
+
text: '',
|
|
70
|
+
edits: [],
|
|
71
|
+
status: 'idle',
|
|
72
|
+
bundleReady: false,
|
|
73
|
+
bundleError: undefined,
|
|
74
|
+
});
|
|
75
|
+
// Get config reference
|
|
76
|
+
const getConfig = () => props.config;
|
|
77
|
+
// Get auth token (cached after first call)
|
|
78
|
+
const getAuthToken = async () => {
|
|
79
|
+
const config = getConfig();
|
|
80
|
+
// Return cached token if available
|
|
81
|
+
if (cachedTokenRef)
|
|
82
|
+
return cachedTokenRef;
|
|
83
|
+
// Reuse in-flight promise if one exists
|
|
84
|
+
if (tokenPromiseRef)
|
|
85
|
+
return tokenPromiseRef;
|
|
86
|
+
if (config.getSession) {
|
|
87
|
+
tokenPromiseRef = (async () => {
|
|
88
|
+
try {
|
|
89
|
+
const session = await config.getSession();
|
|
90
|
+
cachedTokenRef = session.token;
|
|
91
|
+
return session.token;
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
finally {
|
|
97
|
+
tokenPromiseRef = null;
|
|
98
|
+
}
|
|
99
|
+
})();
|
|
100
|
+
return tokenPromiseRef;
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
};
|
|
104
|
+
// Get bundle loader
|
|
105
|
+
const getBundleLoader = () => {
|
|
106
|
+
if (!bundleLoaderRef) {
|
|
107
|
+
bundleLoaderRef = createBundleLoader({
|
|
108
|
+
getAuthToken,
|
|
109
|
+
includeCredentials: true,
|
|
110
|
+
onError: (error) => {
|
|
111
|
+
console.error('[DynimProvider] Bundle load failed:', error);
|
|
112
|
+
getConfig().onError?.(error);
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
return bundleLoaderRef;
|
|
117
|
+
};
|
|
118
|
+
// Load bundle
|
|
119
|
+
const loadBundle = async (bundleUrl) => {
|
|
120
|
+
const loader = getBundleLoader();
|
|
121
|
+
if (loader.isLoading())
|
|
122
|
+
return;
|
|
123
|
+
isBundleLoading.value = true;
|
|
124
|
+
bundleError.value = null;
|
|
125
|
+
try {
|
|
126
|
+
const { App, cleanup } = await loader.load(bundleUrl);
|
|
127
|
+
TenantApp.value = App;
|
|
128
|
+
isBundleLoaded.value = true;
|
|
129
|
+
cleanup();
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
// 404 = no bundle, 401 = not authenticated - show children
|
|
133
|
+
if (error instanceof BundleNotFoundError || error instanceof BundleAuthError) {
|
|
134
|
+
TenantApp.value = null;
|
|
135
|
+
isBundleLoaded.value = false;
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
bundleError.value = error;
|
|
139
|
+
}
|
|
140
|
+
finally {
|
|
141
|
+
isBundleLoading.value = false;
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
// Load saved bundle
|
|
145
|
+
const loadSavedBundle = async () => {
|
|
146
|
+
await loadBundle('/api/code/bundle');
|
|
147
|
+
};
|
|
148
|
+
// Fetch theme
|
|
149
|
+
const fetchTheme = async () => {
|
|
150
|
+
if (hasAttemptedThemeLoadRef)
|
|
151
|
+
return;
|
|
152
|
+
if (!getConfig().getSession)
|
|
153
|
+
return;
|
|
154
|
+
hasAttemptedThemeLoadRef = true;
|
|
155
|
+
try {
|
|
156
|
+
const token = await getAuthToken();
|
|
157
|
+
const headers = {};
|
|
158
|
+
if (token) {
|
|
159
|
+
headers['Authorization'] = `Bearer ${token}`;
|
|
160
|
+
}
|
|
161
|
+
const response = await fetch('/api/code/theme', {
|
|
162
|
+
headers,
|
|
163
|
+
credentials: 'include',
|
|
164
|
+
});
|
|
165
|
+
if (response.ok) {
|
|
166
|
+
const data = await response.json();
|
|
167
|
+
theme.value = data;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
// Theme fetch failed - use defaults (non-critical)
|
|
172
|
+
console.warn('[DynimProvider] Failed to fetch theme:', error);
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
// Public methods
|
|
176
|
+
const enterBuilder = () => {
|
|
177
|
+
if (builderRef && !builderRef.isActive()) {
|
|
178
|
+
builderRef.enter();
|
|
179
|
+
// Fetch theme lazily when entering builder
|
|
180
|
+
fetchTheme();
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
const exitBuilder = () => {
|
|
184
|
+
if (builderRef && builderRef.isActive()) {
|
|
185
|
+
builderRef.exit();
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
const sendCode = async (query) => {
|
|
189
|
+
await codeClientRef?.sendCode(query);
|
|
190
|
+
};
|
|
191
|
+
const saveCode = async () => {
|
|
192
|
+
await codeClientRef?.saveCode();
|
|
193
|
+
await loadSavedBundle();
|
|
194
|
+
};
|
|
195
|
+
const abandonCode = async () => {
|
|
196
|
+
await codeClientRef?.abandonCode();
|
|
197
|
+
await loadSavedBundle();
|
|
198
|
+
};
|
|
199
|
+
// Context value (computed for reactivity)
|
|
200
|
+
const contextValue = computed(() => ({
|
|
201
|
+
enterBuilder,
|
|
202
|
+
exitBuilder,
|
|
203
|
+
isEditing: isEditing.value,
|
|
204
|
+
sendCode,
|
|
205
|
+
saveCode,
|
|
206
|
+
abandonCode,
|
|
207
|
+
codeMessage,
|
|
208
|
+
isBundleLoaded: isBundleLoaded.value,
|
|
209
|
+
isBundleLoading: isBundleLoading.value,
|
|
210
|
+
}));
|
|
211
|
+
// Theme CSS (computed)
|
|
212
|
+
const themeCSS = computed(() => generateThemeCSS(theme.value ?? undefined));
|
|
213
|
+
// Lifecycle: Setup on mount
|
|
214
|
+
onMounted(() => {
|
|
215
|
+
const config = getConfig();
|
|
216
|
+
const { packages = {}, hooks = {}, contexts = {} } = config;
|
|
217
|
+
// Keep loadBundleRef updated
|
|
218
|
+
loadBundleRef = loadBundle;
|
|
219
|
+
// Set up shared context for bundles
|
|
220
|
+
const sdkPackages = {
|
|
221
|
+
'dynim-vue': { DynimProvider, useDynim },
|
|
222
|
+
...packages,
|
|
223
|
+
};
|
|
224
|
+
if (!isSharedContextReady()) {
|
|
225
|
+
// Create fresh shared context
|
|
226
|
+
createSharedContext({
|
|
227
|
+
Vue,
|
|
228
|
+
packages: sdkPackages,
|
|
229
|
+
hooks,
|
|
230
|
+
contexts,
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
// Update existing context with packages (handles HMR)
|
|
235
|
+
updateSharedContext({
|
|
236
|
+
packages: sdkPackages,
|
|
237
|
+
hooks,
|
|
238
|
+
contexts,
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
// Initialize code client
|
|
242
|
+
codeClientRef = createCodeClient({
|
|
243
|
+
getSession: config.getSession,
|
|
244
|
+
onMessageUpdate: (message) => {
|
|
245
|
+
Object.assign(codeMessage, message);
|
|
246
|
+
},
|
|
247
|
+
onError: (error) => {
|
|
248
|
+
console.error('[DynimProvider] Code error:', error);
|
|
249
|
+
config.onError?.(error);
|
|
250
|
+
},
|
|
251
|
+
});
|
|
252
|
+
// Initialize builder
|
|
253
|
+
builderRef = createBuilder({
|
|
254
|
+
getSession: config.getSession,
|
|
255
|
+
codeClient: codeClientRef ?? undefined,
|
|
256
|
+
onExitStart: () => {
|
|
257
|
+
isExitingRef = true;
|
|
258
|
+
isBuilderActiveRef = false;
|
|
259
|
+
codeClientRef?.abort();
|
|
260
|
+
codeClientRef?.resetMessage();
|
|
261
|
+
},
|
|
262
|
+
loadBundle: (bundleUrl) => {
|
|
263
|
+
isExitingRef = true;
|
|
264
|
+
return loadBundleRef?.(bundleUrl) ?? Promise.resolve();
|
|
265
|
+
},
|
|
266
|
+
onEnter: () => {
|
|
267
|
+
isExitingRef = false;
|
|
268
|
+
isBuilderActiveRef = true;
|
|
269
|
+
isEditing.value = true;
|
|
270
|
+
},
|
|
271
|
+
onExit: () => {
|
|
272
|
+
isEditing.value = false;
|
|
273
|
+
},
|
|
274
|
+
});
|
|
275
|
+
// Initialize builder client
|
|
276
|
+
builderClientRef = createBuilderClient({
|
|
277
|
+
getSession: config.getSession,
|
|
278
|
+
onError: (error) => {
|
|
279
|
+
console.error('[DynimProvider] Error:', error);
|
|
280
|
+
config.onError?.(error);
|
|
281
|
+
},
|
|
282
|
+
});
|
|
283
|
+
// Auto-load saved bundle on mount if auth is available
|
|
284
|
+
if (!hasAttemptedInitialLoadRef) {
|
|
285
|
+
hasAttemptedInitialLoadRef = true;
|
|
286
|
+
// No auth configured = skip bundle load
|
|
287
|
+
if (!config.getSession) {
|
|
288
|
+
isInitialLoadComplete.value = true;
|
|
289
|
+
}
|
|
290
|
+
else {
|
|
291
|
+
// Load bundle with the provided token
|
|
292
|
+
const doInitialLoad = async () => {
|
|
293
|
+
try {
|
|
294
|
+
await loadBundleRef?.('/api/code/bundle');
|
|
295
|
+
}
|
|
296
|
+
catch (error) {
|
|
297
|
+
// Errors handled in loadBundle (404 = no bundle, etc.)
|
|
298
|
+
console.log('[DynimProvider] Initial bundle load:', error.message);
|
|
299
|
+
}
|
|
300
|
+
finally {
|
|
301
|
+
isInitialLoadComplete.value = true;
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
doInitialLoad();
|
|
305
|
+
// Prefetch theme after 3s delay (non-blocking, so it's ready when builder opens)
|
|
306
|
+
setTimeout(() => {
|
|
307
|
+
fetchTheme();
|
|
308
|
+
}, 3000);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
// Cleanup on unmount
|
|
313
|
+
onUnmounted(() => {
|
|
314
|
+
builderRef?.destroy();
|
|
315
|
+
});
|
|
316
|
+
// Watch for bundleReady
|
|
317
|
+
watch(() => ({ bundleReady: codeMessage.bundleReady, projectId: codeMessage.projectId }), ({ bundleReady, projectId }) => {
|
|
318
|
+
if (bundleReady && projectId) {
|
|
319
|
+
if (isBuilderActiveRef && !isExitingRef) {
|
|
320
|
+
pendingBundleProjectIdRef = projectId;
|
|
321
|
+
bundleLoadSignal.value++;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
// Watch for bundle load signal
|
|
326
|
+
watch(bundleLoadSignal, (signal) => {
|
|
327
|
+
if (signal === 0)
|
|
328
|
+
return;
|
|
329
|
+
const projectId = pendingBundleProjectIdRef;
|
|
330
|
+
if (!projectId || isExitingRef) {
|
|
331
|
+
pendingBundleProjectIdRef = null;
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
const bundleUrl = `/api/code/bundle?temp=true&_t=${Date.now()}`;
|
|
335
|
+
loadBundleRef?.(bundleUrl);
|
|
336
|
+
pendingBundleProjectIdRef = null;
|
|
337
|
+
});
|
|
338
|
+
// Provide context
|
|
339
|
+
provide(DynimInjectionKey, contextValue.value);
|
|
340
|
+
// Watch for context value changes and update provided value
|
|
341
|
+
watch(contextValue, (newValue) => {
|
|
342
|
+
provide(DynimInjectionKey, newValue);
|
|
343
|
+
});
|
|
344
|
+
// Render function
|
|
345
|
+
return () => {
|
|
346
|
+
// Render content
|
|
347
|
+
const renderContent = () => {
|
|
348
|
+
if (!isInitialLoadComplete.value)
|
|
349
|
+
return null;
|
|
350
|
+
if (bundleError.value) {
|
|
351
|
+
return [
|
|
352
|
+
h('div', {
|
|
353
|
+
style: {
|
|
354
|
+
padding: '12px',
|
|
355
|
+
background: '#fef3c7',
|
|
356
|
+
borderBottom: '1px solid #fcd34d',
|
|
357
|
+
fontSize: '13px',
|
|
358
|
+
color: '#92400e',
|
|
359
|
+
},
|
|
360
|
+
}, `Bundle error: ${bundleError.value.message}`),
|
|
361
|
+
slots.default?.(),
|
|
362
|
+
];
|
|
363
|
+
}
|
|
364
|
+
if (TenantApp.value) {
|
|
365
|
+
return h(TenantApp.value);
|
|
366
|
+
}
|
|
367
|
+
return slots.default?.();
|
|
368
|
+
};
|
|
369
|
+
return [
|
|
370
|
+
h('style', themeCSS.value),
|
|
371
|
+
renderContent(),
|
|
372
|
+
];
|
|
373
|
+
};
|
|
374
|
+
},
|
|
375
|
+
});
|
|
376
|
+
/**
|
|
377
|
+
* Composable to access Dynim functionality
|
|
378
|
+
*/
|
|
379
|
+
export function useDynim() {
|
|
380
|
+
const context = inject(DynimInjectionKey);
|
|
381
|
+
if (!context) {
|
|
382
|
+
throw new Error('useDynim must be used within a DynimProvider');
|
|
383
|
+
}
|
|
384
|
+
return context;
|
|
385
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dynim-vue - Vue 3 integration for Dynim
|
|
3
|
+
*
|
|
4
|
+
* Simple usage:
|
|
5
|
+
* ```vue
|
|
6
|
+
* <script setup>
|
|
7
|
+
* import { DynimProvider, useDynim } from 'dynim-vue';
|
|
8
|
+
* </script>
|
|
9
|
+
*
|
|
10
|
+
* <template>
|
|
11
|
+
* <DynimProvider>
|
|
12
|
+
* <App />
|
|
13
|
+
* </DynimProvider>
|
|
14
|
+
* </template>
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export { DynimProvider, useDynim, DynimInjectionKey } from './DynimProvider';
|
|
18
|
+
export type { DynimConfig, DynimContextValue } from './DynimProvider';
|
|
19
|
+
export { defaultTheme } from './theme';
|
|
20
|
+
export type { DynimTheme } from './theme';
|
|
21
|
+
export type { CodeMessage, CodeEdit, Message } from 'dynim-core';
|
|
22
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAC7E,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAGtE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAG1C,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dynim-vue - Vue 3 integration for Dynim
|
|
3
|
+
*
|
|
4
|
+
* Simple usage:
|
|
5
|
+
* ```vue
|
|
6
|
+
* <script setup>
|
|
7
|
+
* import { DynimProvider, useDynim } from 'dynim-vue';
|
|
8
|
+
* </script>
|
|
9
|
+
*
|
|
10
|
+
* <template>
|
|
11
|
+
* <DynimProvider>
|
|
12
|
+
* <App />
|
|
13
|
+
* </DynimProvider>
|
|
14
|
+
* </template>
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
// Main exports
|
|
18
|
+
export { DynimProvider, useDynim, DynimInjectionKey } from './DynimProvider';
|
|
19
|
+
// Theme customization
|
|
20
|
+
export { defaultTheme } from './theme';
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { DynimGlobal } from 'dynim-core';
|
|
2
|
+
import type { DynimSDKConfig } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Creates and registers the shared context on the window object.
|
|
5
|
+
* This makes Vue, hooks, and contexts available to tenant bundles.
|
|
6
|
+
*
|
|
7
|
+
* Uses createSharedRegistry from dynim-core under the hood.
|
|
8
|
+
*
|
|
9
|
+
* @param config - Configuration object containing Vue, hooks, and contexts
|
|
10
|
+
* @returns The created SDK object
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* import { createSharedContext } from 'dynim-vue';
|
|
15
|
+
* import * as Vue from 'vue';
|
|
16
|
+
* import { useAuth, useNotifications } from './composables';
|
|
17
|
+
*
|
|
18
|
+
* createSharedContext({
|
|
19
|
+
* Vue,
|
|
20
|
+
* hooks: { useAuth, useNotifications },
|
|
21
|
+
* });
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare function createSharedContext(config: DynimSDKConfig): DynimGlobal;
|
|
25
|
+
/**
|
|
26
|
+
* Updates the shared context with additional configuration.
|
|
27
|
+
* Useful for adding packages or hooks after initial creation.
|
|
28
|
+
*
|
|
29
|
+
* @param config - Partial configuration to merge into existing context
|
|
30
|
+
*/
|
|
31
|
+
export declare function updateSharedContext(config: Partial<DynimSDKConfig>): void;
|
|
32
|
+
/**
|
|
33
|
+
* Checks if the shared context has been initialized.
|
|
34
|
+
*
|
|
35
|
+
* @returns true if the shared context is available
|
|
36
|
+
*/
|
|
37
|
+
export declare function isSharedContextReady(): boolean;
|
|
38
|
+
//# sourceMappingURL=sharedContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sharedContext.d.ts","sourceRoot":"","sources":["../../src/inference/sharedContext.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAkB,MAAM,YAAY,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAK9C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,cAAc,GAAG,WAAW,CA2BvE;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,IAAI,CAYzE;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAE9C"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { createSharedRegistry, isSharedRegistryReady, } from 'dynim-core';
|
|
2
|
+
// Keep a reference to the current registry for updates
|
|
3
|
+
let currentRegistry = null;
|
|
4
|
+
/**
|
|
5
|
+
* Creates and registers the shared context on the window object.
|
|
6
|
+
* This makes Vue, hooks, and contexts available to tenant bundles.
|
|
7
|
+
*
|
|
8
|
+
* Uses createSharedRegistry from dynim-core under the hood.
|
|
9
|
+
*
|
|
10
|
+
* @param config - Configuration object containing Vue, hooks, and contexts
|
|
11
|
+
* @returns The created SDK object
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { createSharedContext } from 'dynim-vue';
|
|
16
|
+
* import * as Vue from 'vue';
|
|
17
|
+
* import { useAuth, useNotifications } from './composables';
|
|
18
|
+
*
|
|
19
|
+
* createSharedContext({
|
|
20
|
+
* Vue,
|
|
21
|
+
* hooks: { useAuth, useNotifications },
|
|
22
|
+
* });
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export function createSharedContext(config) {
|
|
26
|
+
const { Vue, hooks = {}, contexts = {}, packages = {}, globals = {} } = config;
|
|
27
|
+
// Always include Vue in packages for bundle access
|
|
28
|
+
const allPackages = {
|
|
29
|
+
'vue': Vue,
|
|
30
|
+
...packages,
|
|
31
|
+
};
|
|
32
|
+
// Create registry using core's createSharedRegistry
|
|
33
|
+
currentRegistry = createSharedRegistry({
|
|
34
|
+
framework: { Vue },
|
|
35
|
+
packages: allPackages,
|
|
36
|
+
hooks,
|
|
37
|
+
contexts,
|
|
38
|
+
globals: {
|
|
39
|
+
// Include Vue at top level for backwards compatibility
|
|
40
|
+
Vue,
|
|
41
|
+
...globals,
|
|
42
|
+
},
|
|
43
|
+
// Expose Vue globally for legacy bundles
|
|
44
|
+
exposeFrameworkGlobally: true,
|
|
45
|
+
frameworkGlobalNames: ['Vue'],
|
|
46
|
+
});
|
|
47
|
+
// Return the created SDK object
|
|
48
|
+
return currentRegistry.get();
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Updates the shared context with additional configuration.
|
|
52
|
+
* Useful for adding packages or hooks after initial creation.
|
|
53
|
+
*
|
|
54
|
+
* @param config - Partial configuration to merge into existing context
|
|
55
|
+
*/
|
|
56
|
+
export function updateSharedContext(config) {
|
|
57
|
+
if (!currentRegistry) {
|
|
58
|
+
console.warn('[sharedContext] Cannot update: shared context not initialized');
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
currentRegistry.update({
|
|
62
|
+
packages: config.packages,
|
|
63
|
+
hooks: config.hooks,
|
|
64
|
+
contexts: config.contexts,
|
|
65
|
+
globals: config.globals,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Checks if the shared context has been initialized.
|
|
70
|
+
*
|
|
71
|
+
* @returns true if the shared context is available
|
|
72
|
+
*/
|
|
73
|
+
export function isSharedContextReady() {
|
|
74
|
+
return isSharedRegistryReady();
|
|
75
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration for the Dynim SDK registration (Vue)
|
|
3
|
+
*/
|
|
4
|
+
export interface DynimSDKConfig {
|
|
5
|
+
/** Vue library instance to expose globally */
|
|
6
|
+
Vue: typeof import('vue');
|
|
7
|
+
/** Custom composables/hooks to expose to tenant bundles */
|
|
8
|
+
hooks?: Record<string, unknown>;
|
|
9
|
+
/** Vue contexts (provide/inject values) to expose to tenant bundles */
|
|
10
|
+
contexts?: Record<string, unknown>;
|
|
11
|
+
/** NPM packages to expose to tenant bundles (e.g., vue-router, pinia) */
|
|
12
|
+
packages?: Record<string, unknown>;
|
|
13
|
+
/** Additional globals to expose */
|
|
14
|
+
globals?: Record<string, unknown>;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/inference/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,8CAA8C;IAC9C,GAAG,EAAE,cAAc,KAAK,CAAC,CAAC;IAC1B,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,uEAAuE;IACvE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,yEAAyE;IACzE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,mCAAmC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/theme.d.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dynim Theme System
|
|
3
|
+
*
|
|
4
|
+
* Theme is automatically fetched from the API per project.
|
|
5
|
+
* CSS variables are injected with defaults matching the original design.
|
|
6
|
+
*/
|
|
7
|
+
export interface DynimTheme {
|
|
8
|
+
accent?: string;
|
|
9
|
+
accentHover?: string;
|
|
10
|
+
builderBg?: string;
|
|
11
|
+
builderText?: string;
|
|
12
|
+
builderFont?: string;
|
|
13
|
+
builderRadius?: string;
|
|
14
|
+
builderOpacity?: string;
|
|
15
|
+
chatAccent?: string;
|
|
16
|
+
chatBg?: string;
|
|
17
|
+
chatText?: string;
|
|
18
|
+
chatFont?: string;
|
|
19
|
+
chatRadius?: string;
|
|
20
|
+
chatOpacity?: string;
|
|
21
|
+
selectionColor?: string;
|
|
22
|
+
hoverColor?: string;
|
|
23
|
+
selectionRadius?: string;
|
|
24
|
+
selectionOpacity?: string;
|
|
25
|
+
hoverOpacity?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Default theme values - matches original SDK styling exactly
|
|
29
|
+
*/
|
|
30
|
+
export declare const defaultTheme: Required<DynimTheme>;
|
|
31
|
+
/**
|
|
32
|
+
* Generates CSS variable declarations from a theme object
|
|
33
|
+
*/
|
|
34
|
+
export declare function generateThemeCSS(theme?: DynimTheme): string;
|
|
35
|
+
/**
|
|
36
|
+
* CSS variable references for use in styles
|
|
37
|
+
*/
|
|
38
|
+
export declare const themeVars: {
|
|
39
|
+
readonly accent: "var(--dynim-accent)";
|
|
40
|
+
readonly accentHover: "var(--dynim-accent-hover)";
|
|
41
|
+
readonly builderBg: "var(--dynim-builder-bg)";
|
|
42
|
+
readonly builderText: "var(--dynim-builder-text)";
|
|
43
|
+
readonly builderFont: "var(--dynim-builder-font)";
|
|
44
|
+
readonly builderRadius: "var(--dynim-builder-radius)";
|
|
45
|
+
readonly builderOpacity: "var(--dynim-builder-opacity)";
|
|
46
|
+
readonly chatAccent: "var(--dynim-chat-accent)";
|
|
47
|
+
readonly chatBg: "var(--dynim-chat-bg)";
|
|
48
|
+
readonly chatText: "var(--dynim-chat-text)";
|
|
49
|
+
readonly chatFont: "var(--dynim-chat-font)";
|
|
50
|
+
readonly chatRadius: "var(--dynim-chat-radius)";
|
|
51
|
+
readonly chatOpacity: "var(--dynim-chat-opacity)";
|
|
52
|
+
readonly selectionColor: "var(--dynim-selection-color)";
|
|
53
|
+
readonly hoverColor: "var(--dynim-hover-color)";
|
|
54
|
+
readonly selectionRadius: "var(--dynim-selection-radius)";
|
|
55
|
+
readonly selectionOpacity: "var(--dynim-selection-opacity)";
|
|
56
|
+
readonly hoverOpacity: "var(--dynim-hover-opacity)";
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=theme.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,UAAU;IAEzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IAGxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IAGrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,QAAQ,CAAC,UAAU,CAwB7C,CAAC;AA+BF;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,GAAE,UAAe,GAAG,MAAM,CAW/D;AAED;;GAEG;AACH,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;CAwBZ,CAAC"}
|
package/dist/theme.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dynim Theme System
|
|
3
|
+
*
|
|
4
|
+
* Theme is automatically fetched from the API per project.
|
|
5
|
+
* CSS variables are injected with defaults matching the original design.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Default theme values - matches original SDK styling exactly
|
|
9
|
+
*/
|
|
10
|
+
export const defaultTheme = {
|
|
11
|
+
// Builder Bar - original values
|
|
12
|
+
accent: '#3b82f6',
|
|
13
|
+
accentHover: '#2563eb',
|
|
14
|
+
builderBg: '#000000',
|
|
15
|
+
builderText: '#ffffff',
|
|
16
|
+
builderFont: 'system-ui, -apple-system, BlinkMacSystemFont, \'Segoe UI\', Roboto, sans-serif',
|
|
17
|
+
builderRadius: '22px',
|
|
18
|
+
builderOpacity: '0.08',
|
|
19
|
+
// Chat Widget - original values
|
|
20
|
+
chatAccent: '#3b82f6',
|
|
21
|
+
chatBg: '#ffffff',
|
|
22
|
+
chatText: '#1f2937',
|
|
23
|
+
chatFont: 'system-ui, -apple-system, BlinkMacSystemFont, \'Segoe UI\', Roboto, sans-serif',
|
|
24
|
+
chatRadius: '16px',
|
|
25
|
+
chatOpacity: '0.08',
|
|
26
|
+
// Selection - original values
|
|
27
|
+
selectionColor: '#8b5cf6',
|
|
28
|
+
hoverColor: '#0ea5e9',
|
|
29
|
+
selectionRadius: '0',
|
|
30
|
+
selectionOpacity: '0.1',
|
|
31
|
+
hoverOpacity: '0.1',
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* CSS variable names mapped to theme keys
|
|
35
|
+
*/
|
|
36
|
+
const cssVarMap = {
|
|
37
|
+
// Builder Bar
|
|
38
|
+
accent: '--dynim-accent',
|
|
39
|
+
accentHover: '--dynim-accent-hover',
|
|
40
|
+
builderBg: '--dynim-builder-bg',
|
|
41
|
+
builderText: '--dynim-builder-text',
|
|
42
|
+
builderFont: '--dynim-builder-font',
|
|
43
|
+
builderRadius: '--dynim-builder-radius',
|
|
44
|
+
builderOpacity: '--dynim-builder-opacity',
|
|
45
|
+
// Chat Widget
|
|
46
|
+
chatAccent: '--dynim-chat-accent',
|
|
47
|
+
chatBg: '--dynim-chat-bg',
|
|
48
|
+
chatText: '--dynim-chat-text',
|
|
49
|
+
chatFont: '--dynim-chat-font',
|
|
50
|
+
chatRadius: '--dynim-chat-radius',
|
|
51
|
+
chatOpacity: '--dynim-chat-opacity',
|
|
52
|
+
// Selection
|
|
53
|
+
selectionColor: '--dynim-selection-color',
|
|
54
|
+
hoverColor: '--dynim-hover-color',
|
|
55
|
+
selectionRadius: '--dynim-selection-radius',
|
|
56
|
+
selectionOpacity: '--dynim-selection-opacity',
|
|
57
|
+
hoverOpacity: '--dynim-hover-opacity',
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Generates CSS variable declarations from a theme object
|
|
61
|
+
*/
|
|
62
|
+
export function generateThemeCSS(theme = {}) {
|
|
63
|
+
const merged = { ...defaultTheme, ...theme };
|
|
64
|
+
const vars = Object.entries(merged)
|
|
65
|
+
.map(([key, value]) => {
|
|
66
|
+
const cssVar = cssVarMap[key];
|
|
67
|
+
return `${cssVar}: ${value};`;
|
|
68
|
+
})
|
|
69
|
+
.join('\n ');
|
|
70
|
+
return `:root {\n ${vars}\n}`;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* CSS variable references for use in styles
|
|
74
|
+
*/
|
|
75
|
+
export const themeVars = {
|
|
76
|
+
// Builder Bar
|
|
77
|
+
accent: 'var(--dynim-accent)',
|
|
78
|
+
accentHover: 'var(--dynim-accent-hover)',
|
|
79
|
+
builderBg: 'var(--dynim-builder-bg)',
|
|
80
|
+
builderText: 'var(--dynim-builder-text)',
|
|
81
|
+
builderFont: 'var(--dynim-builder-font)',
|
|
82
|
+
builderRadius: 'var(--dynim-builder-radius)',
|
|
83
|
+
builderOpacity: 'var(--dynim-builder-opacity)',
|
|
84
|
+
// Chat Widget
|
|
85
|
+
chatAccent: 'var(--dynim-chat-accent)',
|
|
86
|
+
chatBg: 'var(--dynim-chat-bg)',
|
|
87
|
+
chatText: 'var(--dynim-chat-text)',
|
|
88
|
+
chatFont: 'var(--dynim-chat-font)',
|
|
89
|
+
chatRadius: 'var(--dynim-chat-radius)',
|
|
90
|
+
chatOpacity: 'var(--dynim-chat-opacity)',
|
|
91
|
+
// Selection
|
|
92
|
+
selectionColor: 'var(--dynim-selection-color)',
|
|
93
|
+
hoverColor: 'var(--dynim-hover-color)',
|
|
94
|
+
selectionRadius: 'var(--dynim-selection-radius)',
|
|
95
|
+
selectionOpacity: 'var(--dynim-selection-opacity)',
|
|
96
|
+
hoverOpacity: 'var(--dynim-hover-opacity)',
|
|
97
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDynim.d.ts","sourceRoot":"","sources":["../src/useDynim.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/useDynim.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vite/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vite plugin for Dynim package exposure
|
|
3
|
+
*
|
|
4
|
+
* Generates a virtual module that exports all specified packages,
|
|
5
|
+
* so you don't have to manually import and map each one.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* ```ts
|
|
9
|
+
* // vite.config.ts
|
|
10
|
+
* import { dynimPackages } from 'dynim-vue/vite'
|
|
11
|
+
*
|
|
12
|
+
* export default {
|
|
13
|
+
* plugins: [
|
|
14
|
+
* dynimPackages([
|
|
15
|
+
* 'vue-router',
|
|
16
|
+
* '@tanstack/vue-query',
|
|
17
|
+
* 'axios',
|
|
18
|
+
* ])
|
|
19
|
+
* ]
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* Then in your app:
|
|
24
|
+
* ```ts
|
|
25
|
+
* import packages from 'virtual:dynim-packages'
|
|
26
|
+
*
|
|
27
|
+
* <DynimProvider :config="{ packages }">
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
import type { Plugin } from 'vite';
|
|
31
|
+
export interface DynimPackagesOptions {
|
|
32
|
+
/**
|
|
33
|
+
* List of package names to expose to dynim bundles.
|
|
34
|
+
* These must be installed in your project's node_modules.
|
|
35
|
+
*/
|
|
36
|
+
packages: string[];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Vite plugin that generates a virtual module exporting all specified packages.
|
|
40
|
+
*
|
|
41
|
+
* @param packages - Array of package names, or options object
|
|
42
|
+
* @returns Vite plugin
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* // Simple usage - array of package names
|
|
46
|
+
* dynimPackages(['vue-router', 'axios'])
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* // Options object
|
|
50
|
+
* dynimPackages({ packages: ['vue-router', 'axios'] })
|
|
51
|
+
*/
|
|
52
|
+
export declare function dynimPackages(packagesOrOptions: string[] | DynimPackagesOptions): Plugin;
|
|
53
|
+
export default dynimPackages;
|
|
54
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/vite/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAKlC,MAAM,WAAW,oBAAoB;IACnC;;;OAGG;IACH,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAC3B,iBAAiB,EAAE,MAAM,EAAE,GAAG,oBAAoB,GACjD,MAAM,CAwCR;AAED,eAAe,aAAa,CAAA"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vite plugin for Dynim package exposure
|
|
3
|
+
*
|
|
4
|
+
* Generates a virtual module that exports all specified packages,
|
|
5
|
+
* so you don't have to manually import and map each one.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* ```ts
|
|
9
|
+
* // vite.config.ts
|
|
10
|
+
* import { dynimPackages } from 'dynim-vue/vite'
|
|
11
|
+
*
|
|
12
|
+
* export default {
|
|
13
|
+
* plugins: [
|
|
14
|
+
* dynimPackages([
|
|
15
|
+
* 'vue-router',
|
|
16
|
+
* '@tanstack/vue-query',
|
|
17
|
+
* 'axios',
|
|
18
|
+
* ])
|
|
19
|
+
* ]
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* Then in your app:
|
|
24
|
+
* ```ts
|
|
25
|
+
* import packages from 'virtual:dynim-packages'
|
|
26
|
+
*
|
|
27
|
+
* <DynimProvider :config="{ packages }">
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
const VIRTUAL_MODULE_ID = 'virtual:dynim-packages';
|
|
31
|
+
const RESOLVED_VIRTUAL_MODULE_ID = '\0' + VIRTUAL_MODULE_ID;
|
|
32
|
+
/**
|
|
33
|
+
* Vite plugin that generates a virtual module exporting all specified packages.
|
|
34
|
+
*
|
|
35
|
+
* @param packages - Array of package names, or options object
|
|
36
|
+
* @returns Vite plugin
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* // Simple usage - array of package names
|
|
40
|
+
* dynimPackages(['vue-router', 'axios'])
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* // Options object
|
|
44
|
+
* dynimPackages({ packages: ['vue-router', 'axios'] })
|
|
45
|
+
*/
|
|
46
|
+
export function dynimPackages(packagesOrOptions) {
|
|
47
|
+
const packageNames = Array.isArray(packagesOrOptions)
|
|
48
|
+
? packagesOrOptions
|
|
49
|
+
: packagesOrOptions.packages;
|
|
50
|
+
return {
|
|
51
|
+
name: 'dynim-packages',
|
|
52
|
+
resolveId(id) {
|
|
53
|
+
if (id === VIRTUAL_MODULE_ID) {
|
|
54
|
+
return RESOLVED_VIRTUAL_MODULE_ID;
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
load(id) {
|
|
58
|
+
if (id === RESOLVED_VIRTUAL_MODULE_ID) {
|
|
59
|
+
// Generate import statements for each package
|
|
60
|
+
const imports = packageNames
|
|
61
|
+
.map((name, i) => `import * as _pkg${i} from '${name}'`)
|
|
62
|
+
.join('\n');
|
|
63
|
+
// Generate the packages object entries
|
|
64
|
+
// Spread namespace objects into plain objects so exports are enumerable
|
|
65
|
+
const entries = packageNames
|
|
66
|
+
.map((name, i) => ` '${name}': { ..._pkg${i} }`)
|
|
67
|
+
.join(',\n');
|
|
68
|
+
// Return the generated module code
|
|
69
|
+
return `${imports}
|
|
70
|
+
|
|
71
|
+
const packages = {
|
|
72
|
+
${entries}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export default packages
|
|
76
|
+
export { packages }
|
|
77
|
+
`;
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
export default dynimPackages;
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "dynim-vue",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"import": "./dist/index.js"
|
|
11
|
+
},
|
|
12
|
+
"./vite": {
|
|
13
|
+
"types": "./dist/vite/index.d.ts",
|
|
14
|
+
"import": "./dist/vite/index.js"
|
|
15
|
+
},
|
|
16
|
+
"./vite/virtual-module": {
|
|
17
|
+
"types": "./src/vite/virtual-module.d.ts"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist",
|
|
22
|
+
"src/vite/virtual-module.d.ts",
|
|
23
|
+
"README.md"
|
|
24
|
+
],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsc",
|
|
27
|
+
"dev": "tsc --watch"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"dynim-core": "^1.0.7"
|
|
31
|
+
},
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"vue": ">=3.3.0",
|
|
34
|
+
"vite": ">=4.0.0"
|
|
35
|
+
},
|
|
36
|
+
"peerDependenciesMeta": {
|
|
37
|
+
"vite": {
|
|
38
|
+
"optional": true
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"vue": "^3.5.13",
|
|
43
|
+
"vite": "^5.0.11",
|
|
44
|
+
"typescript": "^5.9.3"
|
|
45
|
+
},
|
|
46
|
+
"license": "MIT"
|
|
47
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type declarations for the virtual:dynim-packages module.
|
|
3
|
+
*
|
|
4
|
+
* To use these types, add to your tsconfig.json:
|
|
5
|
+
* {
|
|
6
|
+
* "compilerOptions": {
|
|
7
|
+
* "types": ["dynim-vue/vite/virtual-module"]
|
|
8
|
+
* }
|
|
9
|
+
* }
|
|
10
|
+
*
|
|
11
|
+
* Or add a reference in a .d.ts file:
|
|
12
|
+
* /// <reference types="dynim-vue/vite/virtual-module" />
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
declare module 'virtual:dynim-packages' {
|
|
16
|
+
/**
|
|
17
|
+
* Object mapping package names to their exports.
|
|
18
|
+
* The actual shape depends on which packages you configured
|
|
19
|
+
* in the dynimPackages() plugin.
|
|
20
|
+
*/
|
|
21
|
+
const packages: Record<string, unknown>
|
|
22
|
+
export default packages
|
|
23
|
+
export { packages }
|
|
24
|
+
}
|