UNPKG

alinea

Version:

[![npm](https://img.shields.io/npm/v/alinea.svg)](https://npmjs.org/package/alinea) [![install size](https://packagephobia.com/badge?p=alinea)](https://packagephobia.com/result?p=alinea)

191 lines (189 loc) 5.01 kB
import "../chunks/chunk-U5RRZUYZ.js"; // src/core/Type.ts import { Cursor } from "alinea/core/pages/Cursor"; import { Expr, and } from "alinea/core/pages/Expr"; import { Field } from "./Field.js"; import { Hint } from "./Hint.js"; import { createId } from "./Id.js"; import { Meta } from "./Meta.js"; import { Section, section } from "./Section.js"; import { createExprData } from "./pages/CreateExprData.js"; import { BinaryOp, ExprData } from "./pages/ExprData.js"; import { RecordShape } from "./shape/RecordShape.js"; import { assign, defineProperty, entries, fromEntries, keys } from "./util/Objects.js"; var TypeTarget = class { }; var Type; ((Type2) => { Type2.Data = Symbol.for("@alinea/Type.Data"); function label(type2) { return type2[Type2.Data].label; } Type2.label = label; function meta(type2) { return type2[Type2.Data].meta; } Type2.meta = meta; function shape(type2) { return type2[Type2.Data].shape; } Type2.shape = shape; function hint(type2) { return type2[Type2.Data].hint; } Type2.hint = hint; function sections(type2) { return type2[Type2.Data].sections; } Type2.sections = sections; function isContainer(type2) { return Boolean(type2[Type2.Data].meta.isContainer); } Type2.isContainer = isContainer; function target(type2) { return type2[Type2.Data].target; } Type2.target = target; function field(type2, name) { return type2[name]; } Type2.field = field; function isType(type2) { return Boolean(type2 && type2[Type2.Data]); } Type2.isType = isType; function blankEntry(name, type2) { return { ...Type2.shape(type2).create(), type: name, id: createId() }; } Type2.blankEntry = blankEntry; })(Type || (Type = {})); function fieldsOfDefinition(definition) { return entries(definition).flatMap(([key, value]) => { if (Field.isField(value)) return [[key, value]]; if (Section.isSection(value)) return entries(Section.fields(value)); return []; }); } var TypeInstance = class { constructor(label, definition) { this.label = label; this.definition = definition; this.meta = this.definition[Meta] || {}; this.shape = new RecordShape( label, fromEntries( fieldsOfDefinition(definition).map(([key, field]) => { return [key, Field.shape(field)]; }) ) ); this.hint = Hint.Object( fromEntries( fieldsOfDefinition(definition).map(([key, field]) => { return [key, Field.hint(field)]; }) ) ); let current = {}; const addCurrent = () => { if (keys(current).length > 0) this.sections.push(section({ definition: current })); current = {}; }; for (const [key, value] of entries(definition)) { if (Field.isField(value)) { current[key] = value; } else if (Section.isSection(value)) { addCurrent(); this.sections.push(value); } } addCurrent(); const name = label; const callable = { [name]: (...condition) => this.call(...condition) }[name]; delete callable.length; this.target = callable; this.defineProperties(callable); } shape; hint; meta; sections = []; target; condition(input) { if (input.length === 0) return void 0; const isConditionalRecord = input.length === 1 && !Expr.isExpr(input[0]); const conditions = isConditionalRecord ? entries(input[0]).map(([key, value]) => { const field = Expr(ExprData.Field({ type: this.target }, key)); return Expr( ExprData.BinOp( field[Expr.Data], BinaryOp.Equals, createExprData(value) ) ); }) : input.map((ev) => Expr(createExprData(ev))); return and(...conditions)[Expr.Data]; } call(...input) { const isConditionalRecord = input.length === 1 && !Expr.isExpr(input[0]); if (isConditionalRecord) return new Cursor.Partial(this.target, input[0]); else return new Cursor.Find({ target: { type: this.target }, where: this.condition(input) }); } field(def, name) { return assign(Expr(ExprData.Field({ type: this.target }, name)), { [Field.Data]: def[Field.Data], [Field.Ref]: def[Field.Ref] }); } defineProperties(instance) { for (const [key, value] of fieldsOfDefinition(this.definition)) { defineProperty(instance, key, { value: this.field(value, key), enumerable: true, configurable: true }); } defineProperty(instance, Type.Data, { value: this, enumerable: false }); } }; function type(label, definition) { const title = typeof label === "string" ? label : "Anonymous"; const def = typeof label === "string" ? definition : label; const instance = new TypeInstance( title, def ); return instance.target; } ((type2) => { type2.meta = Meta; })(type || (type = {})); export { Type, TypeTarget, type };