1import { delay } from "../utils.js"; 2import Slot from "../Slot.js"; 3 4// maps <Slot> components to Slot instances 5const slotMap = new Map(); 6window.slotMap = slotMap; 7 8export default function AncestralSlot(classDef) { 9 return function(opts) { 10 classDef.call(this, opts); 11 12 this.id = Math.random().toString(36).split(".").pop(); 13 this.children = new Set(); 14 15 if (opts.parent) { 16 this.parent = opts.parent; 17 this.parent?.children.add(this); 18 } 19 20 const oldInit = this.initialize; 21 this.initialize = async () => { 22 return oldInit(); 23 }; 24 25 const oldFinalize = this.finalize; 26 this.finalize = async () => { 27 this.parent?.children.delete(this); 28 this.parent = null; 29 await oldFinalize(); 30 }; 31 32 // THIS SHOULD BE A NEW SLOT PLUGIN // 33 // SIGNAL SLOT 34 this.match = async handlers => { 35 for (;;) { 36 const [op, ...args] = await this.capture(); 37 const handler = handlers[op] ?? null; 38 if (handler) { 39 return handler(this, ...args); 40 } 41 } 42 }; 43 44 this.expect = async (...ops) => { 45 for (;;) { 46 const [op, ...args] = await this.capture(); 47 if (ops.includes(op)) { 48 return [op, ...args]; 49 } 50 } 51 }; 52 53 this.broadcast = async (...args) => { 54 await Promise.all( 55 ([...this.children]).map(c => 56 c.answer(...args))); 57 }; 58 59 this.emit = async (...args) => { 60 this.parent?.answer(...args); 61 }; 62 // END SIGNAL SLOT 63 // END OTHER SLOT PLUGINS // 64 65 const OldSlot = Slot; 66 this.Slot = class Slot extends OldSlot {}; 67 this.Slot.slot = this; 68 // ^^ now you can map the react component back to the slot. 69 70 const reactComponent = opts.reactComponent; 71 const oldShow = this.show; 72 this.show = async (compFunc, opts={}) => { 73 74 // apply any wrapper functions so we can get the component list 75 let component = compFunc; 76 while (typeof component === "function") { 77 component = component(); 78 } 79 80 //const newchildren = descend(component); 81 82 this.children = new Set(); 83 const rsp = await oldShow(component, opts); 84 85 return rsp; 86 }; 87 88 function set_sub(list_a, list_b) { 89 return list_a.filter(a => !list_b.includes(a)); 90 } 91 92 93 }; 94} 95 96function reconcile(from, to) { 97 if (from instanceof Array) { 98 return reconcileArray(from, to); 99 } 100 if (node instanceof Object) { 101 return reconcileNode(from, to); 102 } 103 return reconcilePrimitive(from, to); 104} 105 106function reconcileArray(from, to) { 107 if (!(to instanceof Array)) { 108 console.log(`replace array ${from} with ${to}`); 109 return; 110 } 111 112 // this is where you use keys 113 // but do that later 114 const min = Math.min(from.length, to.length); 115 for (let i = 0; i < min; i++) { 116 reconcile(from[i], to[i]); 117 } 118 if (from.length === to.length) { 119 return; 120 } 121 const diff = from.length - to.length; 122 if (diff > 0) { 123 // remove items 124 for (let i = 0; i < diff; i++) { 125 //from[from.length + diff]; 126 } 127 return; 128 } 129 // add items 130} 131 132function reconcileNode(from, to) { 133} 134 135function reconcilePrimitive(from, to) { 136 if (typeof from === typeof to) { 137 if (from !== to) { 138 console.log(`chg primitive ${from} to ${to}`); 139 } 140 } 141} 142 143function descend(node, output=[]) { 144 if (node instanceof Array) { 145 descendArray(node, output); 146 } else if (node instanceof Object) { 147 descendNode(node, output); 148 } 149 return output; 150} 151 152function descendArray(list, output) { 153 for (const node of list) { 154 descend(node, output); 155 } 156} 157 158function descendNode(node, output) {
159 if (node.type && node.type.name === "Slot") { 160 output.push(node.type.slot); 161 return; 162 } 163 if (node.props && node.props.children instanceof Array) { 164 descendArray(node.props.children, output); 165 } 166}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.