@myop/cli 0.1.45 → 0.1.47
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/myop-cli.js +1461 -1207
- package/dist/skills/myop-angular-host/SKILL.md +437 -0
- package/dist/skills/myop-cli/SKILL.md +147 -0
- package/dist/skills/myop-component/SKILL.md +112 -42
- package/dist/skills/myop-component/references/dev-workflow.md +74 -8
- package/dist/skills/myop-react-host/SKILL.md +407 -0
- package/dist/skills/myop-react-host/references/auto-generated-packages.md +70 -0
- package/dist/skills/myop-react-native-host/SKILL.md +438 -0
- package/dist/skills/myop-vue-host/SKILL.md +374 -0
- package/package.json +1 -1
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: myop-vue-host
|
|
3
|
+
description: "Integrate Myop components into Vue 3 applications using @myop/vue. ALWAYS use the MyopComponent Vue component or auto-generated packages — NEVER create iframes manually. Covers MyopComponent props, events, slots, data binding, preloading, auto-generated packages, and local dev setup. Activate when the user is building a Vue app that hosts Myop components, or when you see @myop/vue in package.json."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Myop Vue Host Integration
|
|
7
|
+
|
|
8
|
+
Embed Myop components in Vue 3 applications using `@myop/vue`.
|
|
9
|
+
|
|
10
|
+
## CRITICAL: Always Use the SDK
|
|
11
|
+
|
|
12
|
+
**NEVER create `<iframe>` elements manually. NEVER call `myop_init_interface()` or wire `myop_cta_handler()` directly.**
|
|
13
|
+
|
|
14
|
+
The `@myop/vue` SDK handles all iframe management, communication, loading, error handling, and caching. Always use `<MyopComponent>` or an auto-generated package.
|
|
15
|
+
|
|
16
|
+
```vue
|
|
17
|
+
<!-- WRONG — never do this -->
|
|
18
|
+
<iframe ref="myIframe" src="/component.html" />
|
|
19
|
+
|
|
20
|
+
<!-- CORRECT — always use the SDK -->
|
|
21
|
+
<MyopComponent component-id="abc-123" :data="data" @cta="handleCta" />
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## End-to-End Workflow: Vue App with Myop Components
|
|
25
|
+
|
|
26
|
+
Each Myop component is a **separate project** in its own directory. You create them, develop them, push them to get a `componentId`, then reference that ID in your Vue host app.
|
|
27
|
+
|
|
28
|
+
### Step 1: Create component projects
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# Each component gets its own directory
|
|
32
|
+
mkdir components/sidebar && cd components/sidebar
|
|
33
|
+
npx myop create # Scaffolds index.html + myop.config.json
|
|
34
|
+
# Build the component UI (see myop-component skill), then Ctrl+C
|
|
35
|
+
|
|
36
|
+
cd ../ && mkdir chart && cd chart
|
|
37
|
+
npx myop create
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Step 2: Push components to get IDs
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
cd components/sidebar
|
|
44
|
+
npx myop push # Uploads → componentId written to myop.config.json
|
|
45
|
+
|
|
46
|
+
cd ../chart
|
|
47
|
+
npx myop push
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Step 3: Use in your Vue app
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
cd my-vue-app
|
|
54
|
+
npm install @myop/vue @myop/sdk
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
```vue
|
|
58
|
+
<script setup>
|
|
59
|
+
import { MyopComponent } from "@myop/vue";
|
|
60
|
+
</script>
|
|
61
|
+
|
|
62
|
+
<template>
|
|
63
|
+
<MyopComponent
|
|
64
|
+
component-id="<sidebar-componentId-from-step-2>"
|
|
65
|
+
:data="{ items: ['Home', 'Settings'] }"
|
|
66
|
+
@cta="(action, payload) => console.log(action, payload)"
|
|
67
|
+
style="width: 300px"
|
|
68
|
+
/>
|
|
69
|
+
<MyopComponent
|
|
70
|
+
component-id="<chart-componentId-from-step-2>"
|
|
71
|
+
:data="{ values: [10, 20, 30] }"
|
|
72
|
+
style="flex: 1"
|
|
73
|
+
/>
|
|
74
|
+
</template>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Working locally on existing components (componentId already in code)
|
|
78
|
+
|
|
79
|
+
When you find `componentId` values already used in the codebase and the developer wants to modify those components locally:
|
|
80
|
+
|
|
81
|
+
**Step A: Pull the component source**
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
mkdir components/sidebar && cd components/sidebar
|
|
85
|
+
npx myop pull <componentId>
|
|
86
|
+
# Downloads index.html + creates myop.config.json with the componentId
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**Step B: Start the local dev server**
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
npx myop dev # Serves component on port 9292 with HMR
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**Step C: Point the Vue app to local dev server**
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
import { enableLocalDev } from "@myop/vue";
|
|
99
|
+
enableLocalDev(); // All <MyopComponent> instances load from localhost:9292
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Now edits to `index.html` are reflected instantly in the Vue app.
|
|
103
|
+
|
|
104
|
+
**Step D: Push changes when done**
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
npx myop push # Uploads updated component to the same componentId
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Remove or comment out `enableLocalDev()` to go back to loading from the Myop cloud.
|
|
111
|
+
|
|
112
|
+
**Multiple components:**
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
mkdir -p components && cd components
|
|
116
|
+
npx myop pull <sidebar-id> -o sidebar/index.html
|
|
117
|
+
npx myop pull <chart-id> -o chart/index.html
|
|
118
|
+
npx myop dev -m # Monorepo mode — select which components to serve
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## When This Skill Activates
|
|
122
|
+
|
|
123
|
+
- `@myop/vue` is in `package.json` dependencies
|
|
124
|
+
- User asks to "add a Myop component to Vue", "integrate Myop in Vue"
|
|
125
|
+
- Files import from `@myop/vue`
|
|
126
|
+
|
|
127
|
+
## Installation
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
npm install @myop/vue @myop/sdk
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Requires **Vue 3.5+**.
|
|
134
|
+
|
|
135
|
+
## Quick Start
|
|
136
|
+
|
|
137
|
+
### Option 1: Auto-Generated Package (Recommended)
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
npm install https://cloud.myop.dev/npm/{componentId}/vue
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
```vue
|
|
144
|
+
<script setup lang="ts">
|
|
145
|
+
import { MyComponent } from "@myop/my-component";
|
|
146
|
+
</script>
|
|
147
|
+
|
|
148
|
+
<template>
|
|
149
|
+
<MyComponent
|
|
150
|
+
:data="{ title: 'Hello', items: ['a', 'b'] }"
|
|
151
|
+
@cta="(action, payload) => console.log(action, payload)"
|
|
152
|
+
/>
|
|
153
|
+
</template>
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
The auto-generated package bakes in the `componentId` and exports typed props and events.
|
|
157
|
+
|
|
158
|
+
### Option 2: MyopComponent Directly
|
|
159
|
+
|
|
160
|
+
```vue
|
|
161
|
+
<script setup lang="ts">
|
|
162
|
+
import { MyopComponent } from "@myop/vue";
|
|
163
|
+
</script>
|
|
164
|
+
|
|
165
|
+
<template>
|
|
166
|
+
<MyopComponent
|
|
167
|
+
component-id="your-component-id"
|
|
168
|
+
:data="{ title: 'Hello' }"
|
|
169
|
+
@cta="(action, payload) => console.log(action, payload)"
|
|
170
|
+
/>
|
|
171
|
+
</template>
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## MyopComponent Props
|
|
175
|
+
|
|
176
|
+
| Prop | Type | Default | Description |
|
|
177
|
+
|------|------|---------|-------------|
|
|
178
|
+
| `componentId` | `string` | — | Myop component ID (UUID) |
|
|
179
|
+
| `data` | `TData` | — | Data passed to `myop_init_interface`. Reactive — deep-watched |
|
|
180
|
+
| `on` | `(action, payload) => void` | — | Generic CTA callback (alternative to `@cta` event) |
|
|
181
|
+
| `fadeDuration` | `number` | `200` | Loader fade-out duration in ms |
|
|
182
|
+
| `autoSize` | `boolean` | `false` | Auto-size container to match iframe content |
|
|
183
|
+
| `environment` | `string` | — | Load from specific environment |
|
|
184
|
+
| `preview` | `boolean` | `false` | Load unpublished preview version |
|
|
185
|
+
| `componentConfig` | `IComponentInstanceConfig` | — | Direct config object (advanced) |
|
|
186
|
+
|
|
187
|
+
## Events
|
|
188
|
+
|
|
189
|
+
| Event | Payload | Description |
|
|
190
|
+
|-------|---------|-------------|
|
|
191
|
+
| `@load` | `ITypedMyopComponent` | Component finished loading |
|
|
192
|
+
| `@error` | `string` | Load failure message |
|
|
193
|
+
| `@sizeChange` | `SizeInfo` | Auto-sized component changed dimensions |
|
|
194
|
+
| `@cta` | `action: string, payload: any` | CTA event from component |
|
|
195
|
+
|
|
196
|
+
```vue
|
|
197
|
+
<MyopComponent
|
|
198
|
+
component-id="..."
|
|
199
|
+
:data="data"
|
|
200
|
+
@load="onComponentLoaded"
|
|
201
|
+
@error="onError"
|
|
202
|
+
@cta="handleCta"
|
|
203
|
+
/>
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
```ts
|
|
207
|
+
function handleCta(action: string, payload: any) {
|
|
208
|
+
switch (action) {
|
|
209
|
+
case 'item-selected':
|
|
210
|
+
console.log(payload.itemId);
|
|
211
|
+
break;
|
|
212
|
+
case 'form-submitted':
|
|
213
|
+
console.log(payload);
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## Slots
|
|
220
|
+
|
|
221
|
+
| Slot | Purpose |
|
|
222
|
+
|------|---------|
|
|
223
|
+
| `loader` | Custom loading indicator |
|
|
224
|
+
| `fallback` | Custom error fallback UI |
|
|
225
|
+
|
|
226
|
+
```vue
|
|
227
|
+
<MyopComponent component-id="...">
|
|
228
|
+
<template #loader>
|
|
229
|
+
<div class="spinner">Loading...</div>
|
|
230
|
+
</template>
|
|
231
|
+
<template #fallback>
|
|
232
|
+
<div class="error">Failed to load component</div>
|
|
233
|
+
</template>
|
|
234
|
+
</MyopComponent>
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Data Binding
|
|
238
|
+
|
|
239
|
+
The `data` prop is **deep-watched**. Vue reactivity changes automatically call `myop_init_interface`:
|
|
240
|
+
|
|
241
|
+
```vue
|
|
242
|
+
<script setup>
|
|
243
|
+
import { ref } from 'vue';
|
|
244
|
+
|
|
245
|
+
const count = ref(0);
|
|
246
|
+
</script>
|
|
247
|
+
|
|
248
|
+
<template>
|
|
249
|
+
<button @click="count++">+1</button>
|
|
250
|
+
<MyopComponent
|
|
251
|
+
component-id="counter-display"
|
|
252
|
+
:data="{ count }"
|
|
253
|
+
/>
|
|
254
|
+
</template>
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
**Important:** Vue reactive proxies are automatically stripped (via `JSON.parse(JSON.stringify())`) before passing data to the SDK, so no Vue internals leak into the iframe.
|
|
258
|
+
|
|
259
|
+
## Preloading
|
|
260
|
+
|
|
261
|
+
```ts
|
|
262
|
+
import { preloadComponents, isPreloaded } from "@myop/vue";
|
|
263
|
+
|
|
264
|
+
await preloadComponents(["component-id-1", "component-id-2"]);
|
|
265
|
+
await preloadComponents(["component-id-1"], "staging");
|
|
266
|
+
|
|
267
|
+
if (isPreloaded("component-id-1")) {
|
|
268
|
+
console.log("Will render instantly");
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
## Configuration Functions
|
|
273
|
+
|
|
274
|
+
```ts
|
|
275
|
+
import { enableLocalDev, setCloudRepositoryUrl, setEnvironment } from "@myop/vue";
|
|
276
|
+
|
|
277
|
+
enableLocalDev(); // localhost:9292
|
|
278
|
+
setCloudRepositoryUrl("https://custom"); // Custom URL
|
|
279
|
+
setEnvironment("staging"); // Default environment
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## Accessing Component Instance
|
|
283
|
+
|
|
284
|
+
Via template ref:
|
|
285
|
+
|
|
286
|
+
```vue
|
|
287
|
+
<script setup>
|
|
288
|
+
import { ref } from 'vue';
|
|
289
|
+
|
|
290
|
+
const myopRef = ref(null);
|
|
291
|
+
|
|
292
|
+
function updateManually() {
|
|
293
|
+
myopRef.value?.myopComponent?.props?.myop_init_interface({ title: 'Updated' });
|
|
294
|
+
}
|
|
295
|
+
</script>
|
|
296
|
+
|
|
297
|
+
<template>
|
|
298
|
+
<MyopComponent ref="myopRef" component-id="..." />
|
|
299
|
+
</template>
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
Exposed properties: `myopComponent` (SDK component instance), `isLoaded` (boolean ref).
|
|
303
|
+
|
|
304
|
+
## Generics (TypeScript)
|
|
305
|
+
|
|
306
|
+
The component supports Vue 3 generics for typed `data` and events:
|
|
307
|
+
|
|
308
|
+
```vue
|
|
309
|
+
<script setup lang="ts" generic="TData, TCtaPayloads extends Record<string, any>">
|
|
310
|
+
// TypeScript generics flow through to props and events
|
|
311
|
+
</script>
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
## Complete Example
|
|
315
|
+
|
|
316
|
+
```vue
|
|
317
|
+
<script setup lang="ts">
|
|
318
|
+
import { ref } from 'vue';
|
|
319
|
+
import { MyopComponent, preloadComponents } from '@myop/vue';
|
|
320
|
+
|
|
321
|
+
preloadComponents(['sidebar-abc123']);
|
|
322
|
+
|
|
323
|
+
const tasks = ref([
|
|
324
|
+
{ id: '1', title: 'Review PR', completed: false },
|
|
325
|
+
{ id: '2', title: 'Deploy', completed: true },
|
|
326
|
+
]);
|
|
327
|
+
|
|
328
|
+
function handleCta(action: string, payload: any) {
|
|
329
|
+
if (action === 'task-toggled') {
|
|
330
|
+
const task = tasks.value.find(t => t.id === payload.taskId);
|
|
331
|
+
if (task) task.completed = payload.completed;
|
|
332
|
+
}
|
|
333
|
+
if (action === 'task-deleted') {
|
|
334
|
+
tasks.value = tasks.value.filter(t => t.id !== payload.taskId);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
</script>
|
|
338
|
+
|
|
339
|
+
<template>
|
|
340
|
+
<div style="display: flex; height: 100vh">
|
|
341
|
+
<MyopComponent
|
|
342
|
+
component-id="sidebar-abc123"
|
|
343
|
+
:data="{ tasks }"
|
|
344
|
+
@cta="handleCta"
|
|
345
|
+
style="width: 300px"
|
|
346
|
+
>
|
|
347
|
+
<template #loader>
|
|
348
|
+
<div>Loading...</div>
|
|
349
|
+
</template>
|
|
350
|
+
</MyopComponent>
|
|
351
|
+
</div>
|
|
352
|
+
</template>
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
## Auto-Generated Vue Package
|
|
356
|
+
|
|
357
|
+
```bash
|
|
358
|
+
npm install https://cloud.myop.dev/npm/{componentId}/vue
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
The generated package uses `defineComponent` with the `componentId` baked in. It emits `load`, `error`, `sizeChange`, and `cta` events — same API as `MyopComponent` but without needing a `componentId` prop.
|
|
362
|
+
|
|
363
|
+
## TypeScript Types
|
|
364
|
+
|
|
365
|
+
```ts
|
|
366
|
+
import type {
|
|
367
|
+
IPropTypes, // Full props type
|
|
368
|
+
ITypedMyopComponent, // Component instance with typed props
|
|
369
|
+
IMyopComponentProps, // myop_init_interface + myop_cta_handler
|
|
370
|
+
SizeInfo, // { width, height, autoSizingWidth, autoSizingHeight }
|
|
371
|
+
EventHandlerProps, // Generated event handler types
|
|
372
|
+
KebabToPascal, // Utility type
|
|
373
|
+
} from "@myop/vue";
|
|
374
|
+
```
|