use-scroll-animate 8.8.0 → 9.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +2 -2
  3. package/README_ja.md +2 -2
  4. package/README_zh.md +2 -2
  5. package/bin/usa-codemod-9.mjs +71 -0
  6. package/dist/chunks/manifest-B08-vo9G.cjs +81 -0
  7. package/dist/chunks/manifest-B08-vo9G.cjs.map +1 -0
  8. package/dist/chunks/manifest-PJ0h8RS_.js +76 -0
  9. package/dist/chunks/manifest-PJ0h8RS_.js.map +1 -0
  10. package/dist/components/dsl.cjs +210 -0
  11. package/dist/components/dsl.cjs.map +1 -0
  12. package/dist/components/dsl.d.cts +76 -0
  13. package/dist/components/dsl.d.ts +76 -0
  14. package/dist/components/dsl.js +203 -0
  15. package/dist/components/dsl.js.map +1 -0
  16. package/dist/components/effects.cjs +14 -14
  17. package/dist/components/effects.cjs.map +1 -1
  18. package/dist/components/effects.d.cts +8 -8
  19. package/dist/components/effects.d.ts +8 -8
  20. package/dist/components/effects.js +11 -11
  21. package/dist/components/effects.js.map +1 -1
  22. package/dist/components/fx2.cjs +5 -5
  23. package/dist/components/fx2.js +1 -1
  24. package/dist/components/marketplace.cjs +81 -71
  25. package/dist/components/marketplace.cjs.map +1 -1
  26. package/dist/components/marketplace.d.cts +33 -2
  27. package/dist/components/marketplace.d.ts +33 -2
  28. package/dist/components/marketplace.js +73 -68
  29. package/dist/components/marketplace.js.map +1 -1
  30. package/dist/components/widgets.cjs +593 -186
  31. package/dist/components/widgets.cjs.map +1 -1
  32. package/dist/components/widgets.d.cts +152 -2
  33. package/dist/components/widgets.d.ts +152 -2
  34. package/dist/components/widgets.js +587 -187
  35. package/dist/components/widgets.js.map +1 -1
  36. package/dist/components.umd.js +2 -2
  37. package/dist/components.umd.js.map +1 -1
  38. package/dist/widgets.umd.js +1 -1
  39. package/dist/widgets.umd.js.map +1 -1
  40. package/docs/ROADMAP.md +12 -14
  41. package/docs/components.md +40 -4
  42. package/docs/deprecations.md +4 -0
  43. package/docs/upgrading-9.md +37 -0
  44. package/package.json +33 -2
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var components_marketplace = require('./marketplace.cjs');
3
+ var manifest = require('../chunks/manifest-B08-vo9G.cjs');
4
4
  var components_fxGpu = require('../chunks/gpu-CcdA2D2i.cjs');
5
5
  var components_fxText = require('./fx-text.cjs');
6
6
  var components_fxLight = require('./fx-light.cjs');
@@ -89,10 +89,10 @@ function registerEffectPacks() {
89
89
  components_fxSpatial.registerSpatialPack();
90
90
  }
91
91
 
92
- exports.EFFECT_PACK_FORMAT = components_marketplace.EFFECT_PACK_FORMAT;
93
- exports.loadEffectPack = components_marketplace.loadEffectPack;
94
- exports.packManifest = components_marketplace.packManifest;
95
- exports.validateManifest = components_marketplace.validateManifest;
92
+ exports.EFFECT_PACK_FORMAT = manifest.EFFECT_PACK_FORMAT;
93
+ exports.loadEffectPack = manifest.loadEffectPack;
94
+ exports.packManifest = manifest.packManifest;
95
+ exports.validateManifest = manifest.validateManifest;
96
96
  exports.GLSL_HEAD = components_fxGpu.GLSL_HEAD;
97
97
  exports.GPU_FX = components_fxGpu.GPU_FX;
98
98
  exports.WGSL_HEAD = components_fxGpu.WGSL_HEAD;
@@ -1,4 +1,4 @@
1
- export { EFFECT_PACK_FORMAT, loadEffectPack, packManifest, validateManifest } from './marketplace.js';
1
+ export { E as EFFECT_PACK_FORMAT, l as loadEffectPack, p as packManifest, v as validateManifest } from '../chunks/manifest-PJ0h8RS_.js';
2
2
  import { G as GPU_FX, r as registerGpuPack } from '../chunks/gpu-CB8frFOD.js';
3
3
  export { a as GLSL_HEAD, W as WGSL_HEAD, f as fieldFallback, g as glslToWgsl, s as shaderBackground, b as supportsWebGL2, c as supportsWebGPU, w as webgpuBackground, d as wgslModule } from '../chunks/gpu-CB8frFOD.js';
4
4
  import { TEXT3_FX, registerTextPack } from './fx-text.js';
@@ -1,82 +1,92 @@
1
1
  'use strict';
2
2
 
3
- var registry = require('../chunks/registry-BVklOepd.cjs');
3
+ var manifest = require('../chunks/manifest-B08-vo9G.cjs');
4
+ require('../chunks/registry-BVklOepd.cjs');
4
5
  require('../chunks/base-DoRUZBy-.cjs');
5
6
 
6
- const EFFECT_PACK_FORMAT = 'motionary/effect-pack';
7
- const SEMVER = /^\d+\.\d+\.\d+(?:-[\w.]+)?$/;
8
- const PKG = /^(?:@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/;
9
- /** Build a manifest from an effect pack. */
10
- function packManifest(name, packVersion, effects, extra = {}) {
11
- return {
12
- format: EFFECT_PACK_FORMAT,
13
- version: 1,
14
- name,
15
- packVersion,
16
- ...extra,
17
- effects: effects.map((e) => ({ name: e.name, kind: e.kind, ...(e.description ? { description: e.description } : {}), ...(e.defaults ? { defaults: JSON.parse(JSON.stringify(e.defaults)) } : {}) })),
18
- };
7
+ const MARKETPLACE_FORMAT = 'motionary/marketplace';
8
+ const L = (name, title, description, entry, register, effects, tags, since) => ({ name, title, description, entry, register, effects: effects.split(' '), tags: tags.split(' '), since, author: 'Motionary', official: true });
9
+ /** The first-party catalogue (9.0). */
10
+ const MARKETPLACE = [
11
+ L('motionary/fx/festival', 'Festival', 'Fireworks, lanterns, Christmas snow and spooky floats.', 'motionary/fx/festival', 'registerFestivalPack', 'firework-burst lantern-rise xmas-snow spooky-float', 'holiday celebration seasonal', '8.1'),
12
+ L('motionary/fx/retro', 'Retro', 'Pixel, CRT, VHS and Y2K looks.', 'motionary/fx/retro', 'registerRetroPack', 'pixelate-in crt-power vhs-glitch y2k-shine', 'pixel 8-bit vintage', '8.2'),
13
+ L('motionary/fx/organic', 'Organic', 'Vines, blooms, water drops and breathing blobs.', 'motionary/fx/organic', 'registerOrganicPack', 'vine-grow bloom water-drop breathe', 'nature blob liquid', '8.3'),
14
+ L('motionary/fx/cyber', 'Cyber', 'HUD lock-on, scanlines, holograms and data decode.', 'motionary/fx/cyber', 'registerCyberPack', 'hud-frame scanline-sweep hologram data-decode', 'sci-fi hud glitch', '8.4'),
15
+ L('motionary/fx/paper', 'Paper & hand-drawn', 'Paper unfold, pencil sketch, watercolor and crumple.', 'motionary/fx/paper', 'registerPaperPack', 'paper-unfold pencil-sketch watercolor crumple', 'sketch paper drawing', '8.5'),
16
+ L('motionary/fx/surface', 'Surface themes', 'Neon ignite and pulse, glass frost, neumorphic press.', 'motionary/fx/surface', 'registerSurfacePack', 'neon-ignite neon-pulse glass-frost neu-press', 'neon glassmorphism neumorphism theme', '8.6'),
17
+ L('motionary/fx/gesture', 'Gestures 3.0', 'Swipe and pinch hints, tilt wobble, depth-in.', 'motionary/fx/gesture', 'registerGesture3Pack', 'swipe-hint pinch-hint tilt-wobble depth-in', 'touch onboarding 3d', '8.7'),
18
+ L('motionary/fx/spatial', 'XR / spatial', 'Portal open, orbit-in, spatial float and depth pop.', 'motionary/fx/spatial', 'registerSpatialPack', 'portal-open orbit-in spatial-float depth-pop', 'xr vr visionos 3d', '8.8'),
19
+ ];
20
+ /** Ranked search over listings (name / title / tags / effects / description) (9.0). */
21
+ function searchPlugins(query, list = MARKETPLACE) {
22
+ const q = query.toLowerCase().trim().split(/\s+/).filter(Boolean);
23
+ if (!q.length)
24
+ return list.slice();
25
+ const score = (p) => q.reduce((s, w) => {
26
+ let n = 0;
27
+ if (p.title.toLowerCase().includes(w))
28
+ n += 5;
29
+ if (p.tags.some((t) => t.includes(w)))
30
+ n += 4;
31
+ if (p.effects.some((e) => e.includes(w)))
32
+ n += 3;
33
+ if (p.name.toLowerCase().includes(w))
34
+ n += 2;
35
+ if (p.description.toLowerCase().includes(w))
36
+ n += 1;
37
+ return n ? s + n : -1e9;
38
+ }, 0);
39
+ return list
40
+ .map((p) => [p, score(p)])
41
+ .filter(([, s]) => s > 0)
42
+ .sort((a, b) => b[1] - a[1])
43
+ .map(([p]) => p);
19
44
  }
20
- /** Check a manifest (and optionally the module's effects against it). */
21
- function validateManifest(m, effects) {
22
- const errors = [];
23
- const x = m;
24
- if (!x || typeof x !== 'object')
25
- return { ok: false, errors: ['manifest must be an object'] };
26
- if (x.format !== EFFECT_PACK_FORMAT)
27
- errors.push(`format must be "${EFFECT_PACK_FORMAT}"`);
28
- if (x.version !== 1)
29
- errors.push('version must be 1');
30
- if (!x.name || !PKG.test(x.name))
31
- errors.push('name must be an npm package name');
32
- if (!x.packVersion || !SEMVER.test(x.packVersion))
33
- errors.push('packVersion must be semver (x.y.z)');
34
- if (!Array.isArray(x.effects) || !x.effects.length)
35
- errors.push('effects must be a non-empty array');
36
- const seen = new Set();
37
- for (const e of x.effects || []) {
38
- if (!e || !/^[a-z][a-z0-9-]*$/.test(e.name || ''))
39
- errors.push(`invalid effect name "${e?.name}"`);
40
- else if (seen.has(e.name))
41
- errors.push(`duplicate effect "${e.name}"`);
42
- else
43
- seen.add(e.name);
44
- if (!e || !registry.EFFECT_KINDS.includes(e.kind))
45
- errors.push(`effect "${e?.name}": unknown kind "${e?.kind}"`);
46
- }
47
- if (effects) {
48
- const names = new Set(effects.map((e) => e.name));
49
- for (const n of seen)
50
- if (!names.has(n))
51
- errors.push(`effect "${n}" is in the manifest but not exported`);
52
- for (const n of names)
53
- if (!seen.has(n))
54
- errors.push(`effect "${n}" is exported but missing from the manifest`);
55
- }
56
- return { ok: !errors.length, errors };
45
+ const installed = new Map();
46
+ /** Names of installed plugins → their registered effects (9.0). */
47
+ function installedPlugins() {
48
+ return Object.fromEntries(installed);
57
49
  }
58
50
  /**
59
- * Import an effect pack (a URL / specifier, or an already imported module
60
- * with `effects` / `default` and `manifest`), validate and register it.
61
- * Returns the registered effect names.
51
+ * Install a plugin: `load(entry)` imports the module (default: dynamic `import()`), then its
52
+ * `register*` function runs (first-party listing) or its `effects` are validated and registered
53
+ * through `loadEffectPack` (third-party pack). Returns the registered effect names (9.0).
62
54
  */
63
- async function loadEffectPack(src, opts = {}) {
64
- const mod = typeof src === 'string' ? await import(/* @vite-ignore */ src) : src;
65
- const effects = mod.effects || mod.default || [];
66
- const manifest = opts.manifest || mod.manifest;
67
- const v = validateManifest(manifest, effects);
68
- if (!v.ok)
69
- throw new Error(`[motionary] invalid effect pack: ${v.errors.join('; ')}`);
70
- const clash = effects.filter((e) => registry.hasEffect(e.name));
71
- if (clash.length && !opts.override)
72
- throw new Error(`[motionary] effect pack "${manifest.name}" would replace ${clash.map((e) => e.name).join(', ')} (pass { override: true })`);
73
- for (const e of effects)
74
- registry.registerEffect(e, { override: !!opts.override });
75
- return effects.map((e) => e.name);
55
+ async function installPlugin(p, opts = {}) {
56
+ const listing = typeof p === 'string' ? null : p;
57
+ const entry = listing ? listing.entry : p;
58
+ const key = listing ? listing.name : entry;
59
+ if (installed.has(key))
60
+ return installed.get(key);
61
+ const load = opts.load || ((u) => import(/* @vite-ignore */ u));
62
+ const mod = await load(entry);
63
+ let names;
64
+ if (listing && typeof mod?.[listing.register] === 'function') {
65
+ mod[listing.register]();
66
+ names = listing.effects.slice();
67
+ }
68
+ else
69
+ names = await manifest.loadEffectPack(mod, { override: opts.override, manifest: mod?.manifest });
70
+ installed.set(key, names);
71
+ return names;
72
+ }
73
+ /** Read a marketplace index (`{ format: "motionary/marketplace", version: 1, plugins }`) (9.0). */
74
+ async function fetchMarketplace(url, fetcher = fetch) {
75
+ const r = await fetcher(url);
76
+ const j = await r.json();
77
+ if (j?.format !== MARKETPLACE_FORMAT || j?.version !== 1 || !Array.isArray(j.plugins))
78
+ throw new Error(`[motionary] ${url} is not a ${MARKETPLACE_FORMAT} v1 index`);
79
+ return j.plugins.filter((p) => p && typeof p.name === 'string' && typeof p.entry === 'string').map((p) => ({ title: p.name, description: '', register: '', effects: [], tags: [], since: '', ...p }));
76
80
  }
77
81
 
78
- exports.EFFECT_PACK_FORMAT = EFFECT_PACK_FORMAT;
79
- exports.loadEffectPack = loadEffectPack;
80
- exports.packManifest = packManifest;
81
- exports.validateManifest = validateManifest;
82
+ exports.EFFECT_PACK_FORMAT = manifest.EFFECT_PACK_FORMAT;
83
+ exports.loadEffectPack = manifest.loadEffectPack;
84
+ exports.packManifest = manifest.packManifest;
85
+ exports.validateManifest = manifest.validateManifest;
86
+ exports.MARKETPLACE = MARKETPLACE;
87
+ exports.MARKETPLACE_FORMAT = MARKETPLACE_FORMAT;
88
+ exports.fetchMarketplace = fetchMarketplace;
89
+ exports.installPlugin = installPlugin;
90
+ exports.installedPlugins = installedPlugins;
91
+ exports.searchPlugins = searchPlugins;
82
92
  //# sourceMappingURL=marketplace.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"marketplace.cjs","sources":["../../src/components/fx2/manifest.ts"],"sourcesContent":["/**\n * 6.9 — effect marketplace manifest (`motionary/components/marketplace`).\n *\n * A third-party effect pack is an ES module that exports its effects (an\n * `EffectDefinition[]` as `effects` or `default`) plus a JSON manifest:\n *\n * ```json\n * { \"format\": \"motionary/effect-pack\", \"version\": 1,\n * \"name\": \"@acme/motion-snow\", \"packVersion\": \"1.2.0\",\n * \"description\": \"Snow and frost effects\", \"license\": \"MIT\",\n * \"author\": \"Acme\", \"entry\": \"./dist/index.js\", \"requires\": \">=6.9\",\n * \"effects\": [{ \"name\": \"frost\", \"kind\": \"background\", \"description\": \"…\",\n * \"defaults\": { \"speed\": 1 } }] }\n * ```\n *\n * `packManifest()` writes one from your effects, `validateManifest()` checks\n * one (format, semver, unique kebab-case names, known kinds, effects match\n * the module), and `loadEffectPack()` imports a pack (URL or module),\n * validates it and registers its effects — refusing names that already\n * exist unless `override`.\n */\nimport type { EffectDefinition } from '../fx/registry';\nimport { EFFECT_KINDS, registerEffect, hasEffect } from '../fx/registry';\n\nexport const EFFECT_PACK_FORMAT = 'motionary/effect-pack';\n\nexport interface EffectPackManifest {\n format: typeof EFFECT_PACK_FORMAT;\n version: 1;\n name: string;\n packVersion: string;\n description?: string;\n license?: string;\n author?: string;\n homepage?: string;\n entry?: string;\n requires?: string;\n keywords?: string[];\n effects: { name: string; kind: string; description?: string; defaults?: Record<string, unknown> }[];\n}\n\nconst SEMVER = /^\\d+\\.\\d+\\.\\d+(?:-[\\w.]+)?$/;\nconst PKG = /^(?:@[a-z0-9-~][a-z0-9-._~]*\\/)?[a-z0-9-~][a-z0-9-._~]*$/;\n\n/** Build a manifest from an effect pack. */\nexport function packManifest(name: string, packVersion: string, effects: EffectDefinition[], extra: Partial<Omit<EffectPackManifest, 'format' | 'version' | 'name' | 'packVersion' | 'effects'>> = {}): EffectPackManifest {\n return {\n format: EFFECT_PACK_FORMAT,\n version: 1,\n name,\n packVersion,\n ...extra,\n effects: effects.map((e) => ({ name: e.name, kind: e.kind, ...(e.description ? { description: e.description } : {}), ...(e.defaults ? { defaults: JSON.parse(JSON.stringify(e.defaults)) } : {}) })),\n };\n}\n\n/** Check a manifest (and optionally the module's effects against it). */\nexport function validateManifest(m: unknown, effects?: EffectDefinition[]): { ok: boolean; errors: string[] } {\n const errors: string[] = [];\n const x = m as Partial<EffectPackManifest> | null;\n if (!x || typeof x !== 'object') return { ok: false, errors: ['manifest must be an object'] };\n if (x.format !== EFFECT_PACK_FORMAT) errors.push(`format must be \"${EFFECT_PACK_FORMAT}\"`);\n if (x.version !== 1) errors.push('version must be 1');\n if (!x.name || !PKG.test(x.name)) errors.push('name must be an npm package name');\n if (!x.packVersion || !SEMVER.test(x.packVersion)) errors.push('packVersion must be semver (x.y.z)');\n if (!Array.isArray(x.effects) || !x.effects.length) errors.push('effects must be a non-empty array');\n const seen = new Set<string>();\n for (const e of x.effects || []) {\n if (!e || !/^[a-z][a-z0-9-]*$/.test(e.name || '')) errors.push(`invalid effect name \"${e?.name}\"`);\n else if (seen.has(e.name)) errors.push(`duplicate effect \"${e.name}\"`);\n else seen.add(e.name);\n if (!e || !(EFFECT_KINDS as readonly string[]).includes(e.kind)) errors.push(`effect \"${e?.name}\": unknown kind \"${e?.kind}\"`);\n }\n if (effects) {\n const names = new Set(effects.map((e) => e.name));\n for (const n of seen) if (!names.has(n)) errors.push(`effect \"${n}\" is in the manifest but not exported`);\n for (const n of names) if (!seen.has(n)) errors.push(`effect \"${n}\" is exported but missing from the manifest`);\n }\n return { ok: !errors.length, errors };\n}\n\n/**\n * Import an effect pack (a URL / specifier, or an already imported module\n * with `effects` / `default` and `manifest`), validate and register it.\n * Returns the registered effect names.\n */\nexport async function loadEffectPack(src: string | { effects?: EffectDefinition[]; default?: EffectDefinition[]; manifest?: EffectPackManifest }, opts: { manifest?: EffectPackManifest; override?: boolean } = {}): Promise<string[]> {\n const mod: any = typeof src === 'string' ? await import(/* @vite-ignore */ src) : src;\n const effects: EffectDefinition[] = mod.effects || mod.default || [];\n const manifest = opts.manifest || mod.manifest;\n const v = validateManifest(manifest, effects);\n if (!v.ok) throw new Error(`[motionary] invalid effect pack: ${v.errors.join('; ')}`);\n const clash = effects.filter((e) => hasEffect(e.name));\n if (clash.length && !opts.override) throw new Error(`[motionary] effect pack \"${manifest.name}\" would replace ${clash.map((e) => e.name).join(', ')} (pass { override: true })`);\n for (const e of effects) registerEffect(e, { override: !!opts.override });\n return effects.map((e) => e.name);\n}\n"],"names":["EFFECT_KINDS","hasEffect","registerEffect"],"mappings":";;;;;AAwBO,MAAM,kBAAkB,GAAG;AAiBlC,MAAM,MAAM,GAAG,6BAA6B;AAC5C,MAAM,GAAG,GAAG,0DAA0D;AAEtE;AACM,SAAU,YAAY,CAAC,IAAY,EAAE,WAAmB,EAAE,OAA2B,EAAE,KAAA,GAAsG,EAAE,EAAA;IACnM,OAAO;AACL,QAAA,MAAM,EAAE,kBAAkB;AAC1B,QAAA,OAAO,EAAE,CAAC;QACV,IAAI;QACJ,WAAW;AACX,QAAA,GAAG,KAAK;AACR,QAAA,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,WAAW,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,QAAQ,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;KACrM;AACH;AAEA;AACM,SAAU,gBAAgB,CAAC,CAAU,EAAE,OAA4B,EAAA;IACvE,MAAM,MAAM,GAAa,EAAE;IAC3B,MAAM,CAAC,GAAG,CAAuC;AACjD,IAAA,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,4BAA4B,CAAC,EAAE;AAC7F,IAAA,IAAI,CAAC,CAAC,MAAM,KAAK,kBAAkB;AAAE,QAAA,MAAM,CAAC,IAAI,CAAC,mBAAmB,kBAAkB,CAAA,CAAA,CAAG,CAAC;AAC1F,IAAA,IAAI,CAAC,CAAC,OAAO,KAAK,CAAC;AAAE,QAAA,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC;AACrD,IAAA,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAAE,QAAA,MAAM,CAAC,IAAI,CAAC,kCAAkC,CAAC;AACjF,IAAA,IAAI,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC;AAAE,QAAA,MAAM,CAAC,IAAI,CAAC,oCAAoC,CAAC;AACpG,IAAA,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM;AAAE,QAAA,MAAM,CAAC,IAAI,CAAC,mCAAmC,CAAC;AACpG,IAAA,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU;IAC9B,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,IAAI,EAAE,EAAE;AAC/B,QAAA,IAAI,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,CAAA,qBAAA,EAAwB,CAAC,EAAE,IAAI,CAAA,CAAA,CAAG,CAAC;AAC7F,aAAA,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,CAAA,kBAAA,EAAqB,CAAC,CAAC,IAAI,CAAA,CAAA,CAAG,CAAC;;AACjE,YAAA,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;QACrB,IAAI,CAAC,CAAC,IAAI,CAAEA,qBAAkC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;AAAE,YAAA,MAAM,CAAC,IAAI,CAAC,CAAA,QAAA,EAAW,CAAC,EAAE,IAAI,CAAA,iBAAA,EAAoB,CAAC,EAAE,IAAI,CAAA,CAAA,CAAG,CAAC;IAChI;IACA,IAAI,OAAO,EAAE;AACX,QAAA,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC;QACjD,KAAK,MAAM,CAAC,IAAI,IAAI;AAAE,YAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AAAE,gBAAA,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA,qCAAA,CAAuC,CAAC;QACzG,KAAK,MAAM,CAAC,IAAI,KAAK;AAAE,YAAA,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAAE,gBAAA,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA,2CAAA,CAA6C,CAAC;IACjH;IACA,OAAO,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE;AACvC;AAEA;;;;AAIG;AACI,eAAe,cAAc,CAAC,GAA2G,EAAE,OAA8D,EAAE,EAAA;IAChN,MAAM,GAAG,GAAQ,OAAO,GAAG,KAAK,QAAQ,GAAG,MAAM,0BAA0B,GAAG,CAAC,GAAG,GAAG;IACrF,MAAM,OAAO,GAAuB,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,OAAO,IAAI,EAAE;IACpE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ;IAC9C,MAAM,CAAC,GAAG,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC7C,IAAI,CAAC,CAAC,CAAC,EAAE;AAAE,QAAA,MAAM,IAAI,KAAK,CAAC,CAAA,iCAAA,EAAoC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA,CAAE,CAAC;AACrF,IAAA,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAKC,kBAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACtD,IAAA,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ;AAAE,QAAA,MAAM,IAAI,KAAK,CAAC,CAAA,yBAAA,EAA4B,QAAQ,CAAC,IAAI,CAAA,gBAAA,EAAmB,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA,0BAAA,CAA4B,CAAC;IAChL,KAAK,MAAM,CAAC,IAAI,OAAO;AAAE,QAAAC,uBAAc,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;AACzE,IAAA,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC;AACnC;;;;;;;"}
1
+ {"version":3,"file":"marketplace.cjs","sources":["../../src/components/marketplace/index.ts"],"sourcesContent":["/**\n * `motionary/marketplace` (= `motionary/components/marketplace`, 9.0 GA) —\n * the plugin marketplace. Builds on the 6.9 effect-pack manifest\n * (`packManifest`, `validateManifest`, `loadEffectPack`) with:\n *\n * - **`MARKETPLACE`** — the first-party catalogue: every Motionary effect\n * pack as a marketplace listing (name, entry, effects, tags, since).\n * - **`searchPlugins(query, list?)`** — ranked search over names,\n * descriptions, tags and effect names.\n * - **`installPlugin(listing | url, { load })`** — imports a pack (your\n * `load` can map entries to bundler imports), validates it and registers\n * its effects; remembered by `installedPlugins()`.\n * - **`fetchMarketplace(url)`** — read a third-party index\n * (`{ \"format\": \"motionary/marketplace\", \"version\": 1, \"plugins\": [...] }`).\n */\nimport type { EffectDefinition } from '../fx/registry';\nimport { loadEffectPack } from '../fx2/manifest';\n\nexport { EFFECT_PACK_FORMAT, packManifest, validateManifest, loadEffectPack } from '../fx2/manifest';\nexport type { EffectPackManifest } from '../fx2/manifest';\n\nexport const MARKETPLACE_FORMAT = 'motionary/marketplace';\nexport interface PluginListing {\n name: string;\n title: string;\n description: string;\n entry: string;\n register: string;\n effects: string[];\n tags: string[];\n since: string;\n author?: string;\n official?: boolean;\n}\n\nconst L = (name: string, title: string, description: string, entry: string, register: string, effects: string, tags: string, since: string): PluginListing => ({ name, title, description, entry, register, effects: effects.split(' '), tags: tags.split(' '), since, author: 'Motionary', official: true });\n\n/** The first-party catalogue (9.0). */\nexport const MARKETPLACE: PluginListing[] = [\n L('motionary/fx/festival', 'Festival', 'Fireworks, lanterns, Christmas snow and spooky floats.', 'motionary/fx/festival', 'registerFestivalPack', 'firework-burst lantern-rise xmas-snow spooky-float', 'holiday celebration seasonal', '8.1'),\n L('motionary/fx/retro', 'Retro', 'Pixel, CRT, VHS and Y2K looks.', 'motionary/fx/retro', 'registerRetroPack', 'pixelate-in crt-power vhs-glitch y2k-shine', 'pixel 8-bit vintage', '8.2'),\n L('motionary/fx/organic', 'Organic', 'Vines, blooms, water drops and breathing blobs.', 'motionary/fx/organic', 'registerOrganicPack', 'vine-grow bloom water-drop breathe', 'nature blob liquid', '8.3'),\n L('motionary/fx/cyber', 'Cyber', 'HUD lock-on, scanlines, holograms and data decode.', 'motionary/fx/cyber', 'registerCyberPack', 'hud-frame scanline-sweep hologram data-decode', 'sci-fi hud glitch', '8.4'),\n L('motionary/fx/paper', 'Paper & hand-drawn', 'Paper unfold, pencil sketch, watercolor and crumple.', 'motionary/fx/paper', 'registerPaperPack', 'paper-unfold pencil-sketch watercolor crumple', 'sketch paper drawing', '8.5'),\n L('motionary/fx/surface', 'Surface themes', 'Neon ignite and pulse, glass frost, neumorphic press.', 'motionary/fx/surface', 'registerSurfacePack', 'neon-ignite neon-pulse glass-frost neu-press', 'neon glassmorphism neumorphism theme', '8.6'),\n L('motionary/fx/gesture', 'Gestures 3.0', 'Swipe and pinch hints, tilt wobble, depth-in.', 'motionary/fx/gesture', 'registerGesture3Pack', 'swipe-hint pinch-hint tilt-wobble depth-in', 'touch onboarding 3d', '8.7'),\n L('motionary/fx/spatial', 'XR / spatial', 'Portal open, orbit-in, spatial float and depth pop.', 'motionary/fx/spatial', 'registerSpatialPack', 'portal-open orbit-in spatial-float depth-pop', 'xr vr visionos 3d', '8.8'),\n];\n\n/** Ranked search over listings (name / title / tags / effects / description) (9.0). */\nexport function searchPlugins(query: string, list: PluginListing[] = MARKETPLACE): PluginListing[] {\n const q = query.toLowerCase().trim().split(/\\s+/).filter(Boolean);\n if (!q.length) return list.slice();\n const score = (p: PluginListing) =>\n q.reduce((s, w) => {\n let n = 0;\n if (p.title.toLowerCase().includes(w)) n += 5;\n if (p.tags.some((t) => t.includes(w))) n += 4;\n if (p.effects.some((e) => e.includes(w))) n += 3;\n if (p.name.toLowerCase().includes(w)) n += 2;\n if (p.description.toLowerCase().includes(w)) n += 1;\n return n ? s + n : -1e9;\n }, 0);\n return list\n .map((p) => [p, score(p)] as const)\n .filter(([, s]) => s > 0)\n .sort((a, b) => b[1] - a[1])\n .map(([p]) => p);\n}\n\nconst installed = new Map<string, string[]>();\n/** Names of installed plugins → their registered effects (9.0). */\nexport function installedPlugins(): Record<string, string[]> {\n return Object.fromEntries(installed);\n}\n\n/**\n * Install a plugin: `load(entry)` imports the module (default: dynamic `import()`), then its\n * `register*` function runs (first-party listing) or its `effects` are validated and registered\n * through `loadEffectPack` (third-party pack). Returns the registered effect names (9.0).\n */\nexport async function installPlugin(p: PluginListing | string, opts: { load?: (entry: string) => Promise<any>; override?: boolean } = {}): Promise<string[]> {\n const listing = typeof p === 'string' ? null : p;\n const entry = listing ? listing.entry : (p as string);\n const key = listing ? listing.name : entry;\n if (installed.has(key)) return installed.get(key) as string[];\n const load = opts.load || ((u: string) => import(/* @vite-ignore */ u));\n const mod = await load(entry);\n let names: string[];\n if (listing && typeof mod?.[listing.register] === 'function') {\n mod[listing.register]();\n names = listing.effects.slice();\n } else names = await loadEffectPack(mod as { effects?: EffectDefinition[]; default?: EffectDefinition[] }, { override: opts.override, manifest: mod?.manifest });\n installed.set(key, names);\n return names;\n}\n\n/** Read a marketplace index (`{ format: \"motionary/marketplace\", version: 1, plugins }`) (9.0). */\nexport async function fetchMarketplace(url: string, fetcher: typeof fetch = fetch): Promise<PluginListing[]> {\n const r = await fetcher(url);\n const j = await r.json();\n if (j?.format !== MARKETPLACE_FORMAT || j?.version !== 1 || !Array.isArray(j.plugins)) throw new Error(`[motionary] ${url} is not a ${MARKETPLACE_FORMAT} v1 index`);\n return j.plugins.filter((p: any) => p && typeof p.name === 'string' && typeof p.entry === 'string').map((p: any) => ({ title: p.name, description: '', register: '', effects: [], tags: [], since: '', ...p }));\n}\n"],"names":["loadEffectPack"],"mappings":"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"}
@@ -104,5 +104,36 @@ declare function loadEffectPack(src: string | {
104
104
  override?: boolean;
105
105
  }): Promise<string[]>;
106
106
 
107
- export { EFFECT_PACK_FORMAT, loadEffectPack, packManifest, validateManifest };
108
- export type { EffectPackManifest };
107
+ declare const MARKETPLACE_FORMAT = "motionary/marketplace";
108
+ interface PluginListing {
109
+ name: string;
110
+ title: string;
111
+ description: string;
112
+ entry: string;
113
+ register: string;
114
+ effects: string[];
115
+ tags: string[];
116
+ since: string;
117
+ author?: string;
118
+ official?: boolean;
119
+ }
120
+ /** The first-party catalogue (9.0). */
121
+ declare const MARKETPLACE: PluginListing[];
122
+ /** Ranked search over listings (name / title / tags / effects / description) (9.0). */
123
+ declare function searchPlugins(query: string, list?: PluginListing[]): PluginListing[];
124
+ /** Names of installed plugins → their registered effects (9.0). */
125
+ declare function installedPlugins(): Record<string, string[]>;
126
+ /**
127
+ * Install a plugin: `load(entry)` imports the module (default: dynamic `import()`), then its
128
+ * `register*` function runs (first-party listing) or its `effects` are validated and registered
129
+ * through `loadEffectPack` (third-party pack). Returns the registered effect names (9.0).
130
+ */
131
+ declare function installPlugin(p: PluginListing | string, opts?: {
132
+ load?: (entry: string) => Promise<any>;
133
+ override?: boolean;
134
+ }): Promise<string[]>;
135
+ /** Read a marketplace index (`{ format: "motionary/marketplace", version: 1, plugins }`) (9.0). */
136
+ declare function fetchMarketplace(url: string, fetcher?: typeof fetch): Promise<PluginListing[]>;
137
+
138
+ export { EFFECT_PACK_FORMAT, MARKETPLACE, MARKETPLACE_FORMAT, fetchMarketplace, installPlugin, installedPlugins, loadEffectPack, packManifest, searchPlugins, validateManifest };
139
+ export type { EffectPackManifest, PluginListing };
@@ -104,5 +104,36 @@ declare function loadEffectPack(src: string | {
104
104
  override?: boolean;
105
105
  }): Promise<string[]>;
106
106
 
107
- export { EFFECT_PACK_FORMAT, loadEffectPack, packManifest, validateManifest };
108
- export type { EffectPackManifest };
107
+ declare const MARKETPLACE_FORMAT = "motionary/marketplace";
108
+ interface PluginListing {
109
+ name: string;
110
+ title: string;
111
+ description: string;
112
+ entry: string;
113
+ register: string;
114
+ effects: string[];
115
+ tags: string[];
116
+ since: string;
117
+ author?: string;
118
+ official?: boolean;
119
+ }
120
+ /** The first-party catalogue (9.0). */
121
+ declare const MARKETPLACE: PluginListing[];
122
+ /** Ranked search over listings (name / title / tags / effects / description) (9.0). */
123
+ declare function searchPlugins(query: string, list?: PluginListing[]): PluginListing[];
124
+ /** Names of installed plugins → their registered effects (9.0). */
125
+ declare function installedPlugins(): Record<string, string[]>;
126
+ /**
127
+ * Install a plugin: `load(entry)` imports the module (default: dynamic `import()`), then its
128
+ * `register*` function runs (first-party listing) or its `effects` are validated and registered
129
+ * through `loadEffectPack` (third-party pack). Returns the registered effect names (9.0).
130
+ */
131
+ declare function installPlugin(p: PluginListing | string, opts?: {
132
+ load?: (entry: string) => Promise<any>;
133
+ override?: boolean;
134
+ }): Promise<string[]>;
135
+ /** Read a marketplace index (`{ format: "motionary/marketplace", version: 1, plugins }`) (9.0). */
136
+ declare function fetchMarketplace(url: string, fetcher?: typeof fetch): Promise<PluginListing[]>;
137
+
138
+ export { EFFECT_PACK_FORMAT, MARKETPLACE, MARKETPLACE_FORMAT, fetchMarketplace, installPlugin, installedPlugins, loadEffectPack, packManifest, searchPlugins, validateManifest };
139
+ export type { EffectPackManifest, PluginListing };
@@ -1,77 +1,82 @@
1
- import { hasEffect, registerEffect, EFFECT_KINDS } from '../chunks/registry-CnO7ZVPK.js';
1
+ import { l as loadEffectPack } from '../chunks/manifest-PJ0h8RS_.js';
2
+ export { E as EFFECT_PACK_FORMAT, p as packManifest, v as validateManifest } from '../chunks/manifest-PJ0h8RS_.js';
3
+ import '../chunks/registry-CnO7ZVPK.js';
2
4
  import '../chunks/base-CLuqlLfG.js';
3
5
 
4
- const EFFECT_PACK_FORMAT = 'motionary/effect-pack';
5
- const SEMVER = /^\d+\.\d+\.\d+(?:-[\w.]+)?$/;
6
- const PKG = /^(?:@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/;
7
- /** Build a manifest from an effect pack. */
8
- function packManifest(name, packVersion, effects, extra = {}) {
9
- return {
10
- format: EFFECT_PACK_FORMAT,
11
- version: 1,
12
- name,
13
- packVersion,
14
- ...extra,
15
- effects: effects.map((e) => ({ name: e.name, kind: e.kind, ...(e.description ? { description: e.description } : {}), ...(e.defaults ? { defaults: JSON.parse(JSON.stringify(e.defaults)) } : {}) })),
16
- };
6
+ const MARKETPLACE_FORMAT = 'motionary/marketplace';
7
+ const L = (name, title, description, entry, register, effects, tags, since) => ({ name, title, description, entry, register, effects: effects.split(' '), tags: tags.split(' '), since, author: 'Motionary', official: true });
8
+ /** The first-party catalogue (9.0). */
9
+ const MARKETPLACE = [
10
+ L('motionary/fx/festival', 'Festival', 'Fireworks, lanterns, Christmas snow and spooky floats.', 'motionary/fx/festival', 'registerFestivalPack', 'firework-burst lantern-rise xmas-snow spooky-float', 'holiday celebration seasonal', '8.1'),
11
+ L('motionary/fx/retro', 'Retro', 'Pixel, CRT, VHS and Y2K looks.', 'motionary/fx/retro', 'registerRetroPack', 'pixelate-in crt-power vhs-glitch y2k-shine', 'pixel 8-bit vintage', '8.2'),
12
+ L('motionary/fx/organic', 'Organic', 'Vines, blooms, water drops and breathing blobs.', 'motionary/fx/organic', 'registerOrganicPack', 'vine-grow bloom water-drop breathe', 'nature blob liquid', '8.3'),
13
+ L('motionary/fx/cyber', 'Cyber', 'HUD lock-on, scanlines, holograms and data decode.', 'motionary/fx/cyber', 'registerCyberPack', 'hud-frame scanline-sweep hologram data-decode', 'sci-fi hud glitch', '8.4'),
14
+ L('motionary/fx/paper', 'Paper & hand-drawn', 'Paper unfold, pencil sketch, watercolor and crumple.', 'motionary/fx/paper', 'registerPaperPack', 'paper-unfold pencil-sketch watercolor crumple', 'sketch paper drawing', '8.5'),
15
+ L('motionary/fx/surface', 'Surface themes', 'Neon ignite and pulse, glass frost, neumorphic press.', 'motionary/fx/surface', 'registerSurfacePack', 'neon-ignite neon-pulse glass-frost neu-press', 'neon glassmorphism neumorphism theme', '8.6'),
16
+ L('motionary/fx/gesture', 'Gestures 3.0', 'Swipe and pinch hints, tilt wobble, depth-in.', 'motionary/fx/gesture', 'registerGesture3Pack', 'swipe-hint pinch-hint tilt-wobble depth-in', 'touch onboarding 3d', '8.7'),
17
+ L('motionary/fx/spatial', 'XR / spatial', 'Portal open, orbit-in, spatial float and depth pop.', 'motionary/fx/spatial', 'registerSpatialPack', 'portal-open orbit-in spatial-float depth-pop', 'xr vr visionos 3d', '8.8'),
18
+ ];
19
+ /** Ranked search over listings (name / title / tags / effects / description) (9.0). */
20
+ function searchPlugins(query, list = MARKETPLACE) {
21
+ const q = query.toLowerCase().trim().split(/\s+/).filter(Boolean);
22
+ if (!q.length)
23
+ return list.slice();
24
+ const score = (p) => q.reduce((s, w) => {
25
+ let n = 0;
26
+ if (p.title.toLowerCase().includes(w))
27
+ n += 5;
28
+ if (p.tags.some((t) => t.includes(w)))
29
+ n += 4;
30
+ if (p.effects.some((e) => e.includes(w)))
31
+ n += 3;
32
+ if (p.name.toLowerCase().includes(w))
33
+ n += 2;
34
+ if (p.description.toLowerCase().includes(w))
35
+ n += 1;
36
+ return n ? s + n : -1e9;
37
+ }, 0);
38
+ return list
39
+ .map((p) => [p, score(p)])
40
+ .filter(([, s]) => s > 0)
41
+ .sort((a, b) => b[1] - a[1])
42
+ .map(([p]) => p);
17
43
  }
18
- /** Check a manifest (and optionally the module's effects against it). */
19
- function validateManifest(m, effects) {
20
- const errors = [];
21
- const x = m;
22
- if (!x || typeof x !== 'object')
23
- return { ok: false, errors: ['manifest must be an object'] };
24
- if (x.format !== EFFECT_PACK_FORMAT)
25
- errors.push(`format must be "${EFFECT_PACK_FORMAT}"`);
26
- if (x.version !== 1)
27
- errors.push('version must be 1');
28
- if (!x.name || !PKG.test(x.name))
29
- errors.push('name must be an npm package name');
30
- if (!x.packVersion || !SEMVER.test(x.packVersion))
31
- errors.push('packVersion must be semver (x.y.z)');
32
- if (!Array.isArray(x.effects) || !x.effects.length)
33
- errors.push('effects must be a non-empty array');
34
- const seen = new Set();
35
- for (const e of x.effects || []) {
36
- if (!e || !/^[a-z][a-z0-9-]*$/.test(e.name || ''))
37
- errors.push(`invalid effect name "${e?.name}"`);
38
- else if (seen.has(e.name))
39
- errors.push(`duplicate effect "${e.name}"`);
40
- else
41
- seen.add(e.name);
42
- if (!e || !EFFECT_KINDS.includes(e.kind))
43
- errors.push(`effect "${e?.name}": unknown kind "${e?.kind}"`);
44
- }
45
- if (effects) {
46
- const names = new Set(effects.map((e) => e.name));
47
- for (const n of seen)
48
- if (!names.has(n))
49
- errors.push(`effect "${n}" is in the manifest but not exported`);
50
- for (const n of names)
51
- if (!seen.has(n))
52
- errors.push(`effect "${n}" is exported but missing from the manifest`);
53
- }
54
- return { ok: !errors.length, errors };
44
+ const installed = new Map();
45
+ /** Names of installed plugins → their registered effects (9.0). */
46
+ function installedPlugins() {
47
+ return Object.fromEntries(installed);
55
48
  }
56
49
  /**
57
- * Import an effect pack (a URL / specifier, or an already imported module
58
- * with `effects` / `default` and `manifest`), validate and register it.
59
- * Returns the registered effect names.
50
+ * Install a plugin: `load(entry)` imports the module (default: dynamic `import()`), then its
51
+ * `register*` function runs (first-party listing) or its `effects` are validated and registered
52
+ * through `loadEffectPack` (third-party pack). Returns the registered effect names (9.0).
60
53
  */
61
- async function loadEffectPack(src, opts = {}) {
62
- const mod = typeof src === 'string' ? await import(/* @vite-ignore */ src) : src;
63
- const effects = mod.effects || mod.default || [];
64
- const manifest = opts.manifest || mod.manifest;
65
- const v = validateManifest(manifest, effects);
66
- if (!v.ok)
67
- throw new Error(`[motionary] invalid effect pack: ${v.errors.join('; ')}`);
68
- const clash = effects.filter((e) => hasEffect(e.name));
69
- if (clash.length && !opts.override)
70
- throw new Error(`[motionary] effect pack "${manifest.name}" would replace ${clash.map((e) => e.name).join(', ')} (pass { override: true })`);
71
- for (const e of effects)
72
- registerEffect(e, { override: !!opts.override });
73
- return effects.map((e) => e.name);
54
+ async function installPlugin(p, opts = {}) {
55
+ const listing = typeof p === 'string' ? null : p;
56
+ const entry = listing ? listing.entry : p;
57
+ const key = listing ? listing.name : entry;
58
+ if (installed.has(key))
59
+ return installed.get(key);
60
+ const load = opts.load || ((u) => import(/* @vite-ignore */ u));
61
+ const mod = await load(entry);
62
+ let names;
63
+ if (listing && typeof mod?.[listing.register] === 'function') {
64
+ mod[listing.register]();
65
+ names = listing.effects.slice();
66
+ }
67
+ else
68
+ names = await loadEffectPack(mod, { override: opts.override, manifest: mod?.manifest });
69
+ installed.set(key, names);
70
+ return names;
71
+ }
72
+ /** Read a marketplace index (`{ format: "motionary/marketplace", version: 1, plugins }`) (9.0). */
73
+ async function fetchMarketplace(url, fetcher = fetch) {
74
+ const r = await fetcher(url);
75
+ const j = await r.json();
76
+ if (j?.format !== MARKETPLACE_FORMAT || j?.version !== 1 || !Array.isArray(j.plugins))
77
+ throw new Error(`[motionary] ${url} is not a ${MARKETPLACE_FORMAT} v1 index`);
78
+ return j.plugins.filter((p) => p && typeof p.name === 'string' && typeof p.entry === 'string').map((p) => ({ title: p.name, description: '', register: '', effects: [], tags: [], since: '', ...p }));
74
79
  }
75
80
 
76
- export { EFFECT_PACK_FORMAT, loadEffectPack, packManifest, validateManifest };
81
+ export { MARKETPLACE, MARKETPLACE_FORMAT, fetchMarketplace, installPlugin, installedPlugins, loadEffectPack, searchPlugins };
77
82
  //# sourceMappingURL=marketplace.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"marketplace.js","sources":["../../src/components/fx2/manifest.ts"],"sourcesContent":["/**\n * 6.9 — effect marketplace manifest (`motionary/components/marketplace`).\n *\n * A third-party effect pack is an ES module that exports its effects (an\n * `EffectDefinition[]` as `effects` or `default`) plus a JSON manifest:\n *\n * ```json\n * { \"format\": \"motionary/effect-pack\", \"version\": 1,\n * \"name\": \"@acme/motion-snow\", \"packVersion\": \"1.2.0\",\n * \"description\": \"Snow and frost effects\", \"license\": \"MIT\",\n * \"author\": \"Acme\", \"entry\": \"./dist/index.js\", \"requires\": \">=6.9\",\n * \"effects\": [{ \"name\": \"frost\", \"kind\": \"background\", \"description\": \"…\",\n * \"defaults\": { \"speed\": 1 } }] }\n * ```\n *\n * `packManifest()` writes one from your effects, `validateManifest()` checks\n * one (format, semver, unique kebab-case names, known kinds, effects match\n * the module), and `loadEffectPack()` imports a pack (URL or module),\n * validates it and registers its effects — refusing names that already\n * exist unless `override`.\n */\nimport type { EffectDefinition } from '../fx/registry';\nimport { EFFECT_KINDS, registerEffect, hasEffect } from '../fx/registry';\n\nexport const EFFECT_PACK_FORMAT = 'motionary/effect-pack';\n\nexport interface EffectPackManifest {\n format: typeof EFFECT_PACK_FORMAT;\n version: 1;\n name: string;\n packVersion: string;\n description?: string;\n license?: string;\n author?: string;\n homepage?: string;\n entry?: string;\n requires?: string;\n keywords?: string[];\n effects: { name: string; kind: string; description?: string; defaults?: Record<string, unknown> }[];\n}\n\nconst SEMVER = /^\\d+\\.\\d+\\.\\d+(?:-[\\w.]+)?$/;\nconst PKG = /^(?:@[a-z0-9-~][a-z0-9-._~]*\\/)?[a-z0-9-~][a-z0-9-._~]*$/;\n\n/** Build a manifest from an effect pack. */\nexport function packManifest(name: string, packVersion: string, effects: EffectDefinition[], extra: Partial<Omit<EffectPackManifest, 'format' | 'version' | 'name' | 'packVersion' | 'effects'>> = {}): EffectPackManifest {\n return {\n format: EFFECT_PACK_FORMAT,\n version: 1,\n name,\n packVersion,\n ...extra,\n effects: effects.map((e) => ({ name: e.name, kind: e.kind, ...(e.description ? { description: e.description } : {}), ...(e.defaults ? { defaults: JSON.parse(JSON.stringify(e.defaults)) } : {}) })),\n };\n}\n\n/** Check a manifest (and optionally the module's effects against it). */\nexport function validateManifest(m: unknown, effects?: EffectDefinition[]): { ok: boolean; errors: string[] } {\n const errors: string[] = [];\n const x = m as Partial<EffectPackManifest> | null;\n if (!x || typeof x !== 'object') return { ok: false, errors: ['manifest must be an object'] };\n if (x.format !== EFFECT_PACK_FORMAT) errors.push(`format must be \"${EFFECT_PACK_FORMAT}\"`);\n if (x.version !== 1) errors.push('version must be 1');\n if (!x.name || !PKG.test(x.name)) errors.push('name must be an npm package name');\n if (!x.packVersion || !SEMVER.test(x.packVersion)) errors.push('packVersion must be semver (x.y.z)');\n if (!Array.isArray(x.effects) || !x.effects.length) errors.push('effects must be a non-empty array');\n const seen = new Set<string>();\n for (const e of x.effects || []) {\n if (!e || !/^[a-z][a-z0-9-]*$/.test(e.name || '')) errors.push(`invalid effect name \"${e?.name}\"`);\n else if (seen.has(e.name)) errors.push(`duplicate effect \"${e.name}\"`);\n else seen.add(e.name);\n if (!e || !(EFFECT_KINDS as readonly string[]).includes(e.kind)) errors.push(`effect \"${e?.name}\": unknown kind \"${e?.kind}\"`);\n }\n if (effects) {\n const names = new Set(effects.map((e) => e.name));\n for (const n of seen) if (!names.has(n)) errors.push(`effect \"${n}\" is in the manifest but not exported`);\n for (const n of names) if (!seen.has(n)) errors.push(`effect \"${n}\" is exported but missing from the manifest`);\n }\n return { ok: !errors.length, errors };\n}\n\n/**\n * Import an effect pack (a URL / specifier, or an already imported module\n * with `effects` / `default` and `manifest`), validate and register it.\n * Returns the registered effect names.\n */\nexport async function loadEffectPack(src: string | { effects?: EffectDefinition[]; default?: EffectDefinition[]; manifest?: EffectPackManifest }, opts: { manifest?: EffectPackManifest; override?: boolean } = {}): Promise<string[]> {\n const mod: any = typeof src === 'string' ? await import(/* @vite-ignore */ src) : src;\n const effects: EffectDefinition[] = mod.effects || mod.default || [];\n const manifest = opts.manifest || mod.manifest;\n const v = validateManifest(manifest, effects);\n if (!v.ok) throw new Error(`[motionary] invalid effect pack: ${v.errors.join('; ')}`);\n const clash = effects.filter((e) => hasEffect(e.name));\n if (clash.length && !opts.override) throw new Error(`[motionary] effect pack \"${manifest.name}\" would replace ${clash.map((e) => e.name).join(', ')} (pass { override: true })`);\n for (const e of effects) registerEffect(e, { override: !!opts.override });\n return effects.map((e) => e.name);\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"marketplace.js","sources":["../../src/components/marketplace/index.ts"],"sourcesContent":["/**\n * `motionary/marketplace` (= `motionary/components/marketplace`, 9.0 GA) —\n * the plugin marketplace. Builds on the 6.9 effect-pack manifest\n * (`packManifest`, `validateManifest`, `loadEffectPack`) with:\n *\n * - **`MARKETPLACE`** — the first-party catalogue: every Motionary effect\n * pack as a marketplace listing (name, entry, effects, tags, since).\n * - **`searchPlugins(query, list?)`** — ranked search over names,\n * descriptions, tags and effect names.\n * - **`installPlugin(listing | url, { load })`** — imports a pack (your\n * `load` can map entries to bundler imports), validates it and registers\n * its effects; remembered by `installedPlugins()`.\n * - **`fetchMarketplace(url)`** — read a third-party index\n * (`{ \"format\": \"motionary/marketplace\", \"version\": 1, \"plugins\": [...] }`).\n */\nimport type { EffectDefinition } from '../fx/registry';\nimport { loadEffectPack } from '../fx2/manifest';\n\nexport { EFFECT_PACK_FORMAT, packManifest, validateManifest, loadEffectPack } from '../fx2/manifest';\nexport type { EffectPackManifest } from '../fx2/manifest';\n\nexport const MARKETPLACE_FORMAT = 'motionary/marketplace';\nexport interface PluginListing {\n name: string;\n title: string;\n description: string;\n entry: string;\n register: string;\n effects: string[];\n tags: string[];\n since: string;\n author?: string;\n official?: boolean;\n}\n\nconst L = (name: string, title: string, description: string, entry: string, register: string, effects: string, tags: string, since: string): PluginListing => ({ name, title, description, entry, register, effects: effects.split(' '), tags: tags.split(' '), since, author: 'Motionary', official: true });\n\n/** The first-party catalogue (9.0). */\nexport const MARKETPLACE: PluginListing[] = [\n L('motionary/fx/festival', 'Festival', 'Fireworks, lanterns, Christmas snow and spooky floats.', 'motionary/fx/festival', 'registerFestivalPack', 'firework-burst lantern-rise xmas-snow spooky-float', 'holiday celebration seasonal', '8.1'),\n L('motionary/fx/retro', 'Retro', 'Pixel, CRT, VHS and Y2K looks.', 'motionary/fx/retro', 'registerRetroPack', 'pixelate-in crt-power vhs-glitch y2k-shine', 'pixel 8-bit vintage', '8.2'),\n L('motionary/fx/organic', 'Organic', 'Vines, blooms, water drops and breathing blobs.', 'motionary/fx/organic', 'registerOrganicPack', 'vine-grow bloom water-drop breathe', 'nature blob liquid', '8.3'),\n L('motionary/fx/cyber', 'Cyber', 'HUD lock-on, scanlines, holograms and data decode.', 'motionary/fx/cyber', 'registerCyberPack', 'hud-frame scanline-sweep hologram data-decode', 'sci-fi hud glitch', '8.4'),\n L('motionary/fx/paper', 'Paper & hand-drawn', 'Paper unfold, pencil sketch, watercolor and crumple.', 'motionary/fx/paper', 'registerPaperPack', 'paper-unfold pencil-sketch watercolor crumple', 'sketch paper drawing', '8.5'),\n L('motionary/fx/surface', 'Surface themes', 'Neon ignite and pulse, glass frost, neumorphic press.', 'motionary/fx/surface', 'registerSurfacePack', 'neon-ignite neon-pulse glass-frost neu-press', 'neon glassmorphism neumorphism theme', '8.6'),\n L('motionary/fx/gesture', 'Gestures 3.0', 'Swipe and pinch hints, tilt wobble, depth-in.', 'motionary/fx/gesture', 'registerGesture3Pack', 'swipe-hint pinch-hint tilt-wobble depth-in', 'touch onboarding 3d', '8.7'),\n L('motionary/fx/spatial', 'XR / spatial', 'Portal open, orbit-in, spatial float and depth pop.', 'motionary/fx/spatial', 'registerSpatialPack', 'portal-open orbit-in spatial-float depth-pop', 'xr vr visionos 3d', '8.8'),\n];\n\n/** Ranked search over listings (name / title / tags / effects / description) (9.0). */\nexport function searchPlugins(query: string, list: PluginListing[] = MARKETPLACE): PluginListing[] {\n const q = query.toLowerCase().trim().split(/\\s+/).filter(Boolean);\n if (!q.length) return list.slice();\n const score = (p: PluginListing) =>\n q.reduce((s, w) => {\n let n = 0;\n if (p.title.toLowerCase().includes(w)) n += 5;\n if (p.tags.some((t) => t.includes(w))) n += 4;\n if (p.effects.some((e) => e.includes(w))) n += 3;\n if (p.name.toLowerCase().includes(w)) n += 2;\n if (p.description.toLowerCase().includes(w)) n += 1;\n return n ? s + n : -1e9;\n }, 0);\n return list\n .map((p) => [p, score(p)] as const)\n .filter(([, s]) => s > 0)\n .sort((a, b) => b[1] - a[1])\n .map(([p]) => p);\n}\n\nconst installed = new Map<string, string[]>();\n/** Names of installed plugins → their registered effects (9.0). */\nexport function installedPlugins(): Record<string, string[]> {\n return Object.fromEntries(installed);\n}\n\n/**\n * Install a plugin: `load(entry)` imports the module (default: dynamic `import()`), then its\n * `register*` function runs (first-party listing) or its `effects` are validated and registered\n * through `loadEffectPack` (third-party pack). Returns the registered effect names (9.0).\n */\nexport async function installPlugin(p: PluginListing | string, opts: { load?: (entry: string) => Promise<any>; override?: boolean } = {}): Promise<string[]> {\n const listing = typeof p === 'string' ? null : p;\n const entry = listing ? listing.entry : (p as string);\n const key = listing ? listing.name : entry;\n if (installed.has(key)) return installed.get(key) as string[];\n const load = opts.load || ((u: string) => import(/* @vite-ignore */ u));\n const mod = await load(entry);\n let names: string[];\n if (listing && typeof mod?.[listing.register] === 'function') {\n mod[listing.register]();\n names = listing.effects.slice();\n } else names = await loadEffectPack(mod as { effects?: EffectDefinition[]; default?: EffectDefinition[] }, { override: opts.override, manifest: mod?.manifest });\n installed.set(key, names);\n return names;\n}\n\n/** Read a marketplace index (`{ format: \"motionary/marketplace\", version: 1, plugins }`) (9.0). */\nexport async function fetchMarketplace(url: string, fetcher: typeof fetch = fetch): Promise<PluginListing[]> {\n const r = await fetcher(url);\n const j = await r.json();\n if (j?.format !== MARKETPLACE_FORMAT || j?.version !== 1 || !Array.isArray(j.plugins)) throw new Error(`[motionary] ${url} is not a ${MARKETPLACE_FORMAT} v1 index`);\n return j.plugins.filter((p: any) => p && typeof p.name === 'string' && typeof p.entry === 'string').map((p: any) => ({ title: p.name, description: '', register: '', effects: [], tags: [], since: '', ...p }));\n}\n"],"names":[],"mappings":"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"}