Feat v0.2.3 sdk tasks (#7)
Some checks failed
CI/CD / detect-changes (push) Successful in 23s
CI/CD / test-frontend (push) Successful in 5s
CI/CD / test-go-pg (push) Failing after 2m27s
CI/CD / test-sqlite (push) Successful in 2m34s
CI/CD / build-and-deploy (push) Has been skipped

Co-authored-by: Jeffrey Smith <jasafpro@gmail.com>
Co-committed-by: Jeffrey Smith <jasafpro@gmail.com>
This commit was merged in pull request #7.
This commit is contained in:
2026-03-27 11:06:40 +00:00
committed by xcaliber
parent 57ccf19efb
commit 239a5fb732
26 changed files with 2230 additions and 38 deletions

77
src/js/sw/sdk/slots.js Normal file
View File

@@ -0,0 +1,77 @@
// ==========================================
// Switchboard Core — SDK: Slot System
// ==========================================
// Named shell regions where extensions inject UI.
//
// Factory: createSlots(emitFn)
// ==========================================
/**
* Create the slot registry.
*
* @param {Function} emitFn — events.emit for change notifications
* @returns {object} slots
*/
export function createSlots(emitFn) {
/** @type {Map<string, Array<{id:string, component:Function, priority:number}>>} */
const _registry = new Map();
function _sort(arr) {
arr.sort((a, b) => a.priority - b.priority);
}
return {
/**
* Register a component into a named slot.
* @param {string} name — slot name (e.g. 'toolbar', 'statusbar')
* @param {object} entry — { id, component, priority? }
* @returns {Function} unregister
*/
register(name, { id, component, priority = 100 }) {
if (!_registry.has(name)) _registry.set(name, []);
const list = _registry.get(name);
// Prevent duplicate ids in same slot
const idx = list.findIndex(e => e.id === id);
if (idx !== -1) list.splice(idx, 1);
list.push({ id, component, priority });
_sort(list);
emitFn('slots.changed', { slot: name, action: 'register', id }, { localOnly: true });
return () => this.unregister(name, id);
},
/**
* Remove a component from a slot.
*/
unregister(name, id) {
const list = _registry.get(name);
if (!list) return;
const idx = list.findIndex(e => e.id === id);
if (idx !== -1) {
list.splice(idx, 1);
if (list.length === 0) _registry.delete(name);
emitFn('slots.changed', { slot: name, action: 'unregister', id }, { localOnly: true });
}
},
/**
* Get sorted entries for a slot.
* @param {string} name
* @returns {Array<{id:string, component:Function, priority:number}>}
*/
get(name) {
return _registry.get(name) || [];
},
/**
* List all slot names that have content.
* @returns {string[]}
*/
names() {
return [..._registry.keys()];
},
};
}