export default class Schema { static $$types = {}; specification; constructor(specification) { this.specification = this.constructor.normalize(specification); } static defaultValue({$, concrete}) { if (concrete.defaultValue) { return concrete.defaultValue; } return $.defaultValue(concrete); } defaultValue() { return this.constructor.defaultValue(this.specification); } static deserialize(view, offset, {$, concrete}) { return $.deserialize(view, offset, concrete); } deserialize(view, offset = 0) { return this.constructor.deserialize(view, {value: offset}, this.specification); } static normalize({type, ...rest}) { const $$type = this.$$types[type]; if (!$$type) { throw new TypeError(`unregistered schema type '${type}'`); } return { $: this.$$types[type], concrete: $$type.normalize ? $$type.normalize(rest) : rest, type, }; } static serialize(source, view, offset, {$, concrete}) { return $.serialize(source, view, offset, concrete); } serialize(source, view, offset = 0) { this.constructor.serialize(source, view, offset, this.specification); } static sizeOf(instance, {$, concrete}) { return $.sizeOf(instance, concrete); } sizeOf(instance) { return this.constructor.sizeOf(instance, this.specification); } static size({$, concrete}) { return $.staticSizeOf(concrete); } } const imports = import.meta.glob('./schema-types/*.js', {eager: true, import: 'default'}); for (const path in imports) { Schema.$$types[path.replace(/.\/schema-types\/(.*)\.js/, '$1')] = imports[path](Schema); }