135 lines
4.7 KiB
JavaScript
135 lines
4.7 KiB
JavaScript
/**
|
|
* DreamStack Embed SDK — ~3KB standalone
|
|
* Enables embedding DreamStack apps in any website.
|
|
*
|
|
* Usage:
|
|
* <script src="dreamstack-embed.js"></script>
|
|
* <ds-stream src="https://yourapp.com"></ds-stream>
|
|
*
|
|
* Or via JS API:
|
|
* DreamStack.connect('https://yourapp.com', '#container');
|
|
*/
|
|
(function (root, factory) {
|
|
if (typeof module !== 'undefined' && module.exports) module.exports = factory();
|
|
else root.DreamStack = factory();
|
|
})(typeof globalThis !== 'undefined' ? globalThis : this, function () {
|
|
'use strict';
|
|
|
|
// ── Iframe Embed ──
|
|
function embed(src, container, options) {
|
|
var opts = options || {};
|
|
var el = typeof container === 'string' ? document.querySelector(container) : container;
|
|
if (!el) throw new Error('[DreamStack] Container not found: ' + container);
|
|
|
|
var iframe = document.createElement('iframe');
|
|
iframe.src = src;
|
|
iframe.style.border = 'none';
|
|
iframe.style.width = opts.width || '100%';
|
|
iframe.style.height = opts.height || '400px';
|
|
iframe.style.borderRadius = opts.borderRadius || '12px';
|
|
iframe.style.overflow = 'hidden';
|
|
iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin');
|
|
iframe.setAttribute('loading', 'lazy');
|
|
|
|
if (opts.className) iframe.className = opts.className;
|
|
el.appendChild(iframe);
|
|
|
|
return {
|
|
iframe: iframe,
|
|
destroy: function () { el.removeChild(iframe); },
|
|
resize: function (w, h) {
|
|
iframe.style.width = typeof w === 'number' ? w + 'px' : w;
|
|
iframe.style.height = typeof h === 'number' ? h + 'px' : h;
|
|
}
|
|
};
|
|
}
|
|
|
|
// ── Signal Bridge (bidirectional) ──
|
|
function connect(src, container, options) {
|
|
var handle = embed(src, container, options);
|
|
var listeners = {};
|
|
|
|
// Listen for messages from the DreamStack app
|
|
window.addEventListener('message', function (e) {
|
|
if (e.source !== handle.iframe.contentWindow) return;
|
|
var data = e.data;
|
|
if (data && data.type === 'ds:signal') {
|
|
var name = data.name;
|
|
if (listeners[name]) {
|
|
listeners[name].forEach(function (fn) { fn(data.value); });
|
|
}
|
|
if (listeners['*']) {
|
|
listeners['*'].forEach(function (fn) { fn(name, data.value); });
|
|
}
|
|
}
|
|
});
|
|
|
|
return {
|
|
iframe: handle.iframe,
|
|
destroy: handle.destroy,
|
|
resize: handle.resize,
|
|
|
|
// Send a signal value to the DreamStack app
|
|
send: function (name, value) {
|
|
handle.iframe.contentWindow.postMessage(
|
|
{ type: 'ds:signal', name: name, value: value }, '*'
|
|
);
|
|
},
|
|
|
|
// Listen for signal changes from the DreamStack app
|
|
on: function (name, fn) {
|
|
if (!listeners[name]) listeners[name] = [];
|
|
listeners[name].push(fn);
|
|
return function () {
|
|
listeners[name] = listeners[name].filter(function (f) { return f !== fn; });
|
|
};
|
|
}
|
|
};
|
|
}
|
|
|
|
// ── Web Component: <ds-stream> ──
|
|
if (typeof customElements !== 'undefined') {
|
|
customElements.define('ds-stream', class extends HTMLElement {
|
|
constructor() {
|
|
super();
|
|
this._handle = null;
|
|
}
|
|
|
|
connectedCallback() {
|
|
var src = this.getAttribute('src');
|
|
if (!src) return;
|
|
|
|
var shadow = this.attachShadow({ mode: 'open' });
|
|
var wrapper = document.createElement('div');
|
|
wrapper.style.width = '100%';
|
|
wrapper.style.height = this.getAttribute('height') || '400px';
|
|
shadow.appendChild(wrapper);
|
|
|
|
this._handle = embed(src, wrapper, {
|
|
width: '100%',
|
|
height: '100%',
|
|
borderRadius: this.getAttribute('radius') || '12px'
|
|
});
|
|
}
|
|
|
|
disconnectedCallback() {
|
|
if (this._handle) this._handle.destroy();
|
|
}
|
|
|
|
static get observedAttributes() { return ['src', 'height']; }
|
|
attributeChangedCallback(name, old, val) {
|
|
if (name === 'src' && this._handle) {
|
|
this._handle.iframe.src = val;
|
|
} else if (name === 'height' && this._handle) {
|
|
this._handle.resize('100%', val);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
return {
|
|
embed: embed,
|
|
connect: connect,
|
|
version: '0.1.0'
|
|
};
|
|
});
|