UNPKG

@micro-frame/marko

Version:

A Marko tag for building SSR friendly micro frontends.

144 lines (143 loc) 3.37 kB
var __defProp = Object.defineProperty; var __markAsModule = (target) => __defProp(target, "__esModule", { value: true }); var __export = (target, all) => { __markAsModule(target); for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; __export(exports, { StreamSource: () => StreamSource, createWritable: () => createWritable, getSource: () => getSource }); const kReadableByName = Symbol("stream-source"); class StreamSource { constructor() { this._slots = new Map(); this._invalidateHandlers = new Set(); this._closed = false; } getOrCreateSlot(id) { if (this._slots.has(id)) { return this._slots.get(id); } const newSlot = createWritable(); this._slots.set(id, newSlot); return newSlot; } async run(parserIterator) { while (true) { const { value, done } = await parserIterator.next(); if (done) break; if (value === void 0) { continue; } const [slotId, html, isDone] = value; const slot = this.getOrCreateSlot(slotId); slot.write(html); isDone && slot.end(); } this.close(); } slot(id) { return this._closed ? this._slots.get(id) : this.getOrCreateSlot(id); } close(err) { this._closed = true; this._slots.forEach((slot) => err ? slot.error(err) : slot.end()); } onInvalidate(handler) { this._invalidateHandlers.add(handler); } offInvalidate(handler) { this._invalidateHandlers.delete(handler); } invalidate(newSrc) { this._slots.clear(); this._closed = false; for (const handler of this._invalidateHandlers) { handler(newSrc); } } } function getSource(name, out) { const global = typeof document === "object" ? window : out == null ? void 0 : out.global; if (global === void 0) { throw new Error("Server side out.global is missing."); } const store = global[kReadableByName] ?? (global[kReadableByName] = new Map()); if (store.has(name)) { return store.get(name); } const streamSource = new StreamSource(); store.set(name, streamSource); return streamSource; } function createWritable() { let buf = ""; let done = false; let error = void 0; let pending = void 0; return { write(data) { buf += data; if (pending) { pending.resolve(); pending = void 0; } }, end() { done = true; if (pending) { pending.resolve(); pending = void 0; } }, error(reason) { error = reason; if (pending) { pending.reject(reason); pending = void 0; } }, async next() { if (buf) { const value = buf; buf = ""; return { value, done: false }; } if (done) { return { value: void 0, done: true }; } if (error) { throw error; } await (pending = createDeferred()); return this.next(); } }; } function createDeferred() { let resolve; let reject; const p = new Promise((_resolve, _reject) => { resolve = _resolve; reject = _reject; }); p.resolve = resolve; p.reject = reject; return p; } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { StreamSource, createWritable, getSource });