From d0679fabb040a2eefc29fb72efba29502d0fd35a Mon Sep 17 00:00:00 2001 From: Alex Mikhalev Date: Wed, 20 Nov 2024 11:36:21 +0000 Subject: [PATCH 1/2] For discussion: Web components generation --- browser/cli/atomic.config.json | 7 + browser/cli/src/generateClasses.ts | 150 +- browser/cli/src/generateOntology.ts | 12 +- browser/cli/src/ontologies/dataBrowser.ts | 2745 +++++++++++++++++++++ browser/cli/src/ontologies/index.ts | 11 + 5 files changed, 2919 insertions(+), 6 deletions(-) create mode 100644 browser/cli/atomic.config.json create mode 100644 browser/cli/src/ontologies/dataBrowser.ts create mode 100644 browser/cli/src/ontologies/index.ts diff --git a/browser/cli/atomic.config.json b/browser/cli/atomic.config.json new file mode 100644 index 000000000..ca2a49941 --- /dev/null +++ b/browser/cli/atomic.config.json @@ -0,0 +1,7 @@ +{ + "outputFolder": "./src/ontologies", + "moduleAlias": "@tomic/lib", + "ontologies": [ + "https://atomicdata.dev/ontology/data-browser" + ] +} \ No newline at end of file diff --git a/browser/cli/src/generateClasses.ts b/browser/cli/src/generateClasses.ts index 00af3d767..c081efb72 100644 --- a/browser/cli/src/generateClasses.ts +++ b/browser/cli/src/generateClasses.ts @@ -4,22 +4,35 @@ import { ReverseMapping } from './generateBaseObject.js'; import { PropertyRecord } from './PropertyRecord.js'; import { dedupe } from './utils.js'; +interface GeneratedOutput { + interfaces: string; + webComponents: string; +} + export const generateClasses = ( ontology: Resource, reverseMapping: ReverseMapping, propertyRecord: PropertyRecord, -): string => { +): GeneratedOutput => { const classes = dedupe(ontology.props.classes ?? []); const classStringList = classes.map(subject => { return generateClass(subject, reverseMapping, propertyRecord); }); + const webComponentsList = classes.map(subject => { + return generateWebComponent(subject, reverseMapping, propertyRecord); + }); + const innerStr = classStringList.join('\n'); + const webComponentsStr = webComponentsList.join('\n\n'); - return `interface Classes { - ${innerStr} - }`; + return { + interfaces: `interface Classes { + ${innerStr} + }`, + webComponents: webComponentsStr, + }; }; const generateClass = ( @@ -53,6 +66,135 @@ const generateClass = ( ); }; +const generateWebComponent = ( + subject: string, + reverseMapping: ReverseMapping, + propertyRecord: PropertyRecord, +): string => { + const resource = store.getResourceLoading(subject); + const className = reverseMapping[subject].split('.').pop() || ''; + const requires = resource.props.requires ?? []; + const recommends = resource.props.recommends ?? []; + const properties = [...requires, ...recommends]; + + const kebabCaseName = className + .replace(/([a-z])([A-Z])/g, '$1-$2') + .toLowerCase(); + + return ` +class ${className}Element extends HTMLElement { + static get observedAttributes() { + return ['subject', ${properties + .map(prop => `'${reverseMapping[prop]?.split('.').pop()}'`) + .join(', ')}]; + } + + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + this._resource = null; + this._loading = false; + } + + async connectedCallback() { + this.render(); + await this.loadResource(); + } + + async attributeChangedCallback(name, oldValue, newValue) { + if (name === 'subject' && oldValue !== newValue) { + await this.loadResource(); + } + this.render(); + } + + async loadResource() { + const subject = this.getAttribute('subject'); + if (!subject || this._loading) { + return; + } + + try { + this._loading = true; + this._resource = await store.getResource(subject); + + // Set attributes based on resource properties + ${properties + .map( + prop => ` + const ${reverseMapping[prop]?.split('.').pop()} = this._resource.get('${prop}'); + if (${reverseMapping[prop]?.split('.').pop()}) { + this.setAttribute('${reverseMapping[prop]?.split('.').pop()}', ${reverseMapping[prop]?.split('.').pop()}); + }`, + ) + .join('\n')} + } catch (e) { + console.error('Error loading resource:', e); + } finally { + this._loading = false; + this.render(); + } + } + + render() { + if (!this.shadowRoot) return; + + const loading = this._loading; + const subject = this.getAttribute('subject'); + + this.shadowRoot.innerHTML = \` + +
+ ${properties + .map( + prop => ` +
+ ${reverseMapping[prop]?.split('.').pop()}: + \${this.getAttribute('${reverseMapping[prop]?.split('.').pop()}') || ''} +
`, + ) + .join('\n')} + ${requires + .map( + prop => ` +
+ Required: ${reverseMapping[prop]?.split('.').pop()} +
`, + ) + .join('\n')} +
+ \`; + } +} + +customElements.define('atomic-${kebabCaseName}', ${className}Element);`; +}; + const classString = ( key: string, requires: string[], diff --git a/browser/cli/src/generateOntology.ts b/browser/cli/src/generateOntology.ts index 7969640d0..b7f4679f6 100644 --- a/browser/cli/src/generateOntology.ts +++ b/browser/cli/src/generateOntology.ts @@ -15,6 +15,7 @@ enum Inserts { BASE_OBJECT = '{{2}}', CLASS_EXPORTS = '{{3}}', CLASSES = '{{4}}', + WEB_COMPONENTS = '{{5}}', PROP_TYPE_MAPPING = '{{7}}', PROP_SUBJECT_TO_NAME_MAPPING = '{{8}}', } @@ -31,6 +32,8 @@ ${Inserts.BASE_OBJECT} ${Inserts.CLASS_EXPORTS} +${Inserts.WEB_COMPONENTS} + declare module '${Inserts.MODULE_ALIAS}' { ${Inserts.CLASSES} @@ -56,7 +59,11 @@ export const generateOntology = async ( } const [baseObjStr, reverseMapping] = await generateBaseObject(ontology); - const classesStr = generateClasses(ontology, reverseMapping, propertyRecord); + const classesOutput = generateClasses( + ontology, + reverseMapping, + propertyRecord, + ); const propertiesStr = generatePropTypeMapping(ontology, reverseMapping); const subToNameStr = generateSubjectToNameMapping(ontology, reverseMapping); const classExportsStr = generateClassExports(ontology, reverseMapping); @@ -67,7 +74,8 @@ export const generateOntology = async ( ) .replace(Inserts.BASE_OBJECT, baseObjStr) .replace(Inserts.CLASS_EXPORTS, classExportsStr) - .replace(Inserts.CLASSES, classesStr) + .replace(Inserts.CLASSES, classesOutput.interfaces) + .replace(Inserts.WEB_COMPONENTS, classesOutput.webComponents) .replace(Inserts.PROP_TYPE_MAPPING, propertiesStr) .replace(Inserts.PROP_SUBJECT_TO_NAME_MAPPING, subToNameStr); diff --git a/browser/cli/src/ontologies/dataBrowser.ts b/browser/cli/src/ontologies/dataBrowser.ts new file mode 100644 index 000000000..4ad401750 --- /dev/null +++ b/browser/cli/src/ontologies/dataBrowser.ts @@ -0,0 +1,2745 @@ +/* ----------------------------------- + * GENERATED WITH @tomic/cli + * For more info on how to use ontologies: https://github.com/atomicdata-dev/atomic-server/blob/develop/browser/cli/readme.md + * -------------------------------- */ + +import type { OntologyBaseObject, BaseProps } from '@tomic/lib'; + +export const dataBrowser = { + classes: { + article: 'https://atomicdata.dev/classes/Article', + bookmark: 'https://atomicdata.dev/class/Bookmark', + chatroom: 'https://atomicdata.dev/classes/ChatRoom', + currencyProperty: + 'https://atomicdata.dev/ontology/data-browser/class/currency-property', + dateFormat: 'https://atomicdata.dev/classes/DateFormat', + displayStyle: 'https://atomicdata.dev/class/DisplayStyle', + document: 'https://atomicdata.dev/classes/Document', + floatRangeProperty: 'https://atomicdata.dev/classes/FloatRangeProperty', + folder: 'https://atomicdata.dev/classes/Folder', + formattedDate: 'https://atomicdata.dev/classes/FormattedDate', + formattedNumber: 'https://atomicdata.dev/classes/FormattedNumber', + importer: 'https://atomicdata.dev/classes/Importer', + message: 'https://atomicdata.dev/classes/Message', + numberFormat: 'https://atomicdata.dev/classes/NumberFormat', + paragraph: 'https://atomicdata.dev/classes/elements/Paragraph', + rangeProperty: 'https://atomicdata.dev/classes/RangeProperty', + selectProperty: 'https://atomicdata.dev/classes/SelectProperty', + table: 'https://atomicdata.dev/classes/Table', + tag: 'https://atomicdata.dev/classes/Tag', + template: 'https://atomicdata.dev/ontology/data-browser/class/template', + }, + properties: { + color: 'https://atomicdata.dev/properties/color', + currency: 'https://atomicdata.dev/ontology/data-browser/property/currency', + customNodePositioning: + 'https://atomicdata.dev/properties/custom-node-positioning', + dateFormat: 'https://atomicdata.dev/properties/dateFormat', + decimalPlaces: 'https://atomicdata.dev/properties/decimalPlaces', + displayStyle: 'https://atomicdata.dev/property/display-style', + elements: 'https://atomicdata.dev/properties/documents/elements', + emoji: 'https://atomicdata.dev/properties/emoji', + image: 'https://atomicdata.dev/ontology/data-browser/property/image', + imageUrl: 'https://atomicdata.dev/properties/imageUrl', + max: 'https://atomicdata.dev/properties/max', + maxFloat: 'https://atomicdata.dev/properties/maxFloat', + messages: 'https://atomicdata.dev/properties/messages', + min: 'https://atomicdata.dev/properties/min', + minFloat: 'https://atomicdata.dev/properties/minFloat', + nextPage: 'https://atomicdata.dev/properties/nextPage', + numberFormatting: 'https://atomicdata.dev/properties/numberFormatting', + preview: 'https://atomicdata.dev/property/preview', + publishedAt: 'https://atomicdata.dev/properties/published-at', + replyTo: 'https://atomicdata.dev/properties/replyTo', + resources: + 'https://atomicdata.dev/ontology/data-browser/property/resources', + subResources: 'https://atomicdata.dev/properties/subresources', + tableColumnWidths: 'https://atomicdata.dev/properties/tableColumnWidths', + tags: 'https://atomicdata.dev/properties/tags', + url: 'https://atomicdata.dev/property/url', + }, + __classDefs: { + ['https://atomicdata.dev/classes/Article']: [ + 'https://atomicdata.dev/properties/description', + 'https://atomicdata.dev/properties/name', + 'https://atomicdata.dev/properties/tags', + 'https://atomicdata.dev/properties/published-at', + ], + ['https://atomicdata.dev/class/Bookmark']: [ + 'https://atomicdata.dev/properties/name', + 'https://atomicdata.dev/property/url', + 'https://atomicdata.dev/property/preview', + 'https://atomicdata.dev/properties/description', + 'https://atomicdata.dev/properties/imageUrl', + ], + ['https://atomicdata.dev/classes/ChatRoom']: [ + 'https://atomicdata.dev/properties/name', + 'https://atomicdata.dev/properties/messages', + ], + ['https://atomicdata.dev/ontology/data-browser/class/currency-property']: [ + 'https://atomicdata.dev/ontology/data-browser/property/currency', + ], + ['https://atomicdata.dev/classes/DateFormat']: [ + 'https://atomicdata.dev/properties/shortname', + ], + ['https://atomicdata.dev/class/DisplayStyle']: [ + 'https://atomicdata.dev/properties/name', + ], + ['https://atomicdata.dev/classes/Document']: [ + 'https://atomicdata.dev/properties/documents/elements', + 'https://atomicdata.dev/properties/name', + ], + ['https://atomicdata.dev/classes/FloatRangeProperty']: [ + 'https://atomicdata.dev/properties/minFloat', + 'https://atomicdata.dev/properties/maxFloat', + ], + ['https://atomicdata.dev/classes/Folder']: [ + 'https://atomicdata.dev/properties/name', + 'https://atomicdata.dev/property/display-style', + 'https://atomicdata.dev/properties/subresources', + ], + ['https://atomicdata.dev/classes/FormattedDate']: [ + 'https://atomicdata.dev/properties/dateFormat', + ], + ['https://atomicdata.dev/classes/FormattedNumber']: [ + 'https://atomicdata.dev/properties/numberFormatting', + 'https://atomicdata.dev/properties/decimalPlaces', + ], + ['https://atomicdata.dev/classes/Importer']: [], + ['https://atomicdata.dev/classes/Message']: [ + 'https://atomicdata.dev/properties/description', + 'https://atomicdata.dev/properties/parent', + ], + ['https://atomicdata.dev/classes/NumberFormat']: [ + 'https://atomicdata.dev/properties/shortname', + ], + ['https://atomicdata.dev/classes/elements/Paragraph']: [ + 'https://atomicdata.dev/properties/description', + 'https://atomicdata.dev/properties/parent', + ], + ['https://atomicdata.dev/classes/RangeProperty']: [ + 'https://atomicdata.dev/properties/min', + 'https://atomicdata.dev/properties/max', + ], + ['https://atomicdata.dev/classes/SelectProperty']: [ + 'https://atomicdata.dev/properties/allowsOnly', + 'https://atomicdata.dev/properties/max', + ], + ['https://atomicdata.dev/classes/Table']: [ + 'https://atomicdata.dev/properties/classtype', + 'https://atomicdata.dev/properties/name', + ], + ['https://atomicdata.dev/classes/Tag']: [ + 'https://atomicdata.dev/properties/shortname', + 'https://atomicdata.dev/properties/color', + 'https://atomicdata.dev/properties/emoji', + ], + ['https://atomicdata.dev/ontology/data-browser/class/template']: [ + 'https://atomicdata.dev/properties/name', + 'https://atomicdata.dev/properties/description', + 'https://atomicdata.dev/ontology/data-browser/property/image', + 'https://atomicdata.dev/ontology/data-browser/property/resources', + ], + }, +} as const satisfies OntologyBaseObject; + +export type Article = typeof dataBrowser.classes.article; +export type Bookmark = typeof dataBrowser.classes.bookmark; +export type Chatroom = typeof dataBrowser.classes.chatroom; +export type CurrencyProperty = typeof dataBrowser.classes.currencyProperty; +export type DateFormat = typeof dataBrowser.classes.dateFormat; +export type DisplayStyle = typeof dataBrowser.classes.displayStyle; +export type Document = typeof dataBrowser.classes.document; +export type FloatRangeProperty = typeof dataBrowser.classes.floatRangeProperty; +export type Folder = typeof dataBrowser.classes.folder; +export type FormattedDate = typeof dataBrowser.classes.formattedDate; +export type FormattedNumber = typeof dataBrowser.classes.formattedNumber; +export type Importer = typeof dataBrowser.classes.importer; +export type Message = typeof dataBrowser.classes.message; +export type NumberFormat = typeof dataBrowser.classes.numberFormat; +export type Paragraph = typeof dataBrowser.classes.paragraph; +export type RangeProperty = typeof dataBrowser.classes.rangeProperty; +export type SelectProperty = typeof dataBrowser.classes.selectProperty; +export type Table = typeof dataBrowser.classes.table; +export type Tag = typeof dataBrowser.classes.tag; +export type Template = typeof dataBrowser.classes.template; + +class articleElement extends HTMLElement { + static get observedAttributes() { + return ['subject', 'undefined', 'undefined', 'tags', 'publishedAt']; + } + + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + this._resource = null; + this._loading = false; + } + + async connectedCallback() { + this.render(); + await this.loadResource(); + } + + async attributeChangedCallback(name, oldValue, newValue) { + if (name === 'subject' && oldValue !== newValue) { + await this.loadResource(); + } + this.render(); + } + + async loadResource() { + const subject = this.getAttribute('subject'); + if (!subject || this._loading) { + return; + } + + try { + this._loading = true; + this._resource = await store.getResource(subject); + + // Set attributes based on resource properties + + const undefined = this._resource.get( + 'https://atomicdata.dev/properties/description', + ); + if (undefined) { + this.setAttribute('undefined', undefined); + } + + const undefined = this._resource.get( + 'https://atomicdata.dev/properties/name', + ); + if (undefined) { + this.setAttribute('undefined', undefined); + } + + const tags = this._resource.get('https://atomicdata.dev/properties/tags'); + if (tags) { + this.setAttribute('tags', tags); + } + + const publishedAt = this._resource.get( + 'https://atomicdata.dev/properties/published-at', + ); + if (publishedAt) { + this.setAttribute('publishedAt', publishedAt); + } + } catch (e) { + console.error('Error loading resource:', e); + } finally { + this._loading = false; + this.render(); + } + } + + render() { + if (!this.shadowRoot) return; + + const loading = this._loading; + const subject = this.getAttribute('subject'); + + this.shadowRoot.innerHTML = ` + +
+ +
+ undefined: + ${ + this.getAttribute('undefined') || '' + } +
+ +
+ undefined: + ${ + this.getAttribute('undefined') || '' + } +
+ +
+ tags: + ${this.getAttribute('tags') || ''} +
+ +
+ publishedAt: + ${ + this.getAttribute('publishedAt') || '' + } +
+ +
+ Required: undefined +
+ +
+ Required: undefined +
+
+ `; + } +} + +customElements.define('atomic-article', articleElement); + +class bookmarkElement extends HTMLElement { + static get observedAttributes() { + return ['subject', 'undefined', 'url', 'preview', 'undefined', 'imageUrl']; + } + + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + this._resource = null; + this._loading = false; + } + + async connectedCallback() { + this.render(); + await this.loadResource(); + } + + async attributeChangedCallback(name, oldValue, newValue) { + if (name === 'subject' && oldValue !== newValue) { + await this.loadResource(); + } + this.render(); + } + + async loadResource() { + const subject = this.getAttribute('subject'); + if (!subject || this._loading) { + return; + } + + try { + this._loading = true; + this._resource = await store.getResource(subject); + + // Set attributes based on resource properties + + const undefined = this._resource.get( + 'https://atomicdata.dev/properties/name', + ); + if (undefined) { + this.setAttribute('undefined', undefined); + } + + const url = this._resource.get('https://atomicdata.dev/property/url'); + if (url) { + this.setAttribute('url', url); + } + + const preview = this._resource.get( + 'https://atomicdata.dev/property/preview', + ); + if (preview) { + this.setAttribute('preview', preview); + } + + const undefined = this._resource.get( + 'https://atomicdata.dev/properties/description', + ); + if (undefined) { + this.setAttribute('undefined', undefined); + } + + const imageUrl = this._resource.get( + 'https://atomicdata.dev/properties/imageUrl', + ); + if (imageUrl) { + this.setAttribute('imageUrl', imageUrl); + } + } catch (e) { + console.error('Error loading resource:', e); + } finally { + this._loading = false; + this.render(); + } + } + + render() { + if (!this.shadowRoot) return; + + const loading = this._loading; + const subject = this.getAttribute('subject'); + + this.shadowRoot.innerHTML = ` + +
+ +
+ undefined: + ${ + this.getAttribute('undefined') || '' + } +
+ +
+ url: + ${this.getAttribute('url') || ''} +
+ +
+ preview: + ${ + this.getAttribute('preview') || '' + } +
+ +
+ undefined: + ${ + this.getAttribute('undefined') || '' + } +
+ +
+ imageUrl: + ${ + this.getAttribute('imageUrl') || '' + } +
+ +
+ Required: undefined +
+ +
+ Required: url +
+
+ `; + } +} + +customElements.define('atomic-bookmark', bookmarkElement); + +class chatroomElement extends HTMLElement { + static get observedAttributes() { + return ['subject', 'undefined', 'messages']; + } + + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + this._resource = null; + this._loading = false; + } + + async connectedCallback() { + this.render(); + await this.loadResource(); + } + + async attributeChangedCallback(name, oldValue, newValue) { + if (name === 'subject' && oldValue !== newValue) { + await this.loadResource(); + } + this.render(); + } + + async loadResource() { + const subject = this.getAttribute('subject'); + if (!subject || this._loading) { + return; + } + + try { + this._loading = true; + this._resource = await store.getResource(subject); + + // Set attributes based on resource properties + + const undefined = this._resource.get( + 'https://atomicdata.dev/properties/name', + ); + if (undefined) { + this.setAttribute('undefined', undefined); + } + + const messages = this._resource.get( + 'https://atomicdata.dev/properties/messages', + ); + if (messages) { + this.setAttribute('messages', messages); + } + } catch (e) { + console.error('Error loading resource:', e); + } finally { + this._loading = false; + this.render(); + } + } + + render() { + if (!this.shadowRoot) return; + + const loading = this._loading; + const subject = this.getAttribute('subject'); + + this.shadowRoot.innerHTML = ` + +
+ +
+ undefined: + ${ + this.getAttribute('undefined') || '' + } +
+ +
+ messages: + ${ + this.getAttribute('messages') || '' + } +
+ +
+ Required: undefined +
+
+ `; + } +} + +customElements.define('atomic-chatroom', chatroomElement); + +class currencyPropertyElement extends HTMLElement { + static get observedAttributes() { + return ['subject', 'currency']; + } + + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + this._resource = null; + this._loading = false; + } + + async connectedCallback() { + this.render(); + await this.loadResource(); + } + + async attributeChangedCallback(name, oldValue, newValue) { + if (name === 'subject' && oldValue !== newValue) { + await this.loadResource(); + } + this.render(); + } + + async loadResource() { + const subject = this.getAttribute('subject'); + if (!subject || this._loading) { + return; + } + + try { + this._loading = true; + this._resource = await store.getResource(subject); + + // Set attributes based on resource properties + + const currency = this._resource.get( + 'https://atomicdata.dev/ontology/data-browser/property/currency', + ); + if (currency) { + this.setAttribute('currency', currency); + } + } catch (e) { + console.error('Error loading resource:', e); + } finally { + this._loading = false; + this.render(); + } + } + + render() { + if (!this.shadowRoot) return; + + const loading = this._loading; + const subject = this.getAttribute('subject'); + + this.shadowRoot.innerHTML = ` + +
+ +
+ currency: + ${ + this.getAttribute('currency') || '' + } +
+ +
+ Required: currency +
+
+ `; + } +} + +customElements.define('atomic-currency-property', currencyPropertyElement); + +class dateFormatElement extends HTMLElement { + static get observedAttributes() { + return ['subject', 'undefined']; + } + + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + this._resource = null; + this._loading = false; + } + + async connectedCallback() { + this.render(); + await this.loadResource(); + } + + async attributeChangedCallback(name, oldValue, newValue) { + if (name === 'subject' && oldValue !== newValue) { + await this.loadResource(); + } + this.render(); + } + + async loadResource() { + const subject = this.getAttribute('subject'); + if (!subject || this._loading) { + return; + } + + try { + this._loading = true; + this._resource = await store.getResource(subject); + + // Set attributes based on resource properties + + const undefined = this._resource.get( + 'https://atomicdata.dev/properties/shortname', + ); + if (undefined) { + this.setAttribute('undefined', undefined); + } + } catch (e) { + console.error('Error loading resource:', e); + } finally { + this._loading = false; + this.render(); + } + } + + render() { + if (!this.shadowRoot) return; + + const loading = this._loading; + const subject = this.getAttribute('subject'); + + this.shadowRoot.innerHTML = ` + +
+ +
+ undefined: + ${ + this.getAttribute('undefined') || '' + } +
+ +
+ Required: undefined +
+
+ `; + } +} + +customElements.define('atomic-date-format', dateFormatElement); + +class displayStyleElement extends HTMLElement { + static get observedAttributes() { + return ['subject', 'undefined']; + } + + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + this._resource = null; + this._loading = false; + } + + async connectedCallback() { + this.render(); + await this.loadResource(); + } + + async attributeChangedCallback(name, oldValue, newValue) { + if (name === 'subject' && oldValue !== newValue) { + await this.loadResource(); + } + this.render(); + } + + async loadResource() { + const subject = this.getAttribute('subject'); + if (!subject || this._loading) { + return; + } + + try { + this._loading = true; + this._resource = await store.getResource(subject); + + // Set attributes based on resource properties + + const undefined = this._resource.get( + 'https://atomicdata.dev/properties/name', + ); + if (undefined) { + this.setAttribute('undefined', undefined); + } + } catch (e) { + console.error('Error loading resource:', e); + } finally { + this._loading = false; + this.render(); + } + } + + render() { + if (!this.shadowRoot) return; + + const loading = this._loading; + const subject = this.getAttribute('subject'); + + this.shadowRoot.innerHTML = ` + +
+ +
+ undefined: + ${ + this.getAttribute('undefined') || '' + } +
+ +
+ Required: undefined +
+
+ `; + } +} + +customElements.define('atomic-display-style', displayStyleElement); + +class documentElement extends HTMLElement { + static get observedAttributes() { + return ['subject', 'elements', 'undefined']; + } + + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + this._resource = null; + this._loading = false; + } + + async connectedCallback() { + this.render(); + await this.loadResource(); + } + + async attributeChangedCallback(name, oldValue, newValue) { + if (name === 'subject' && oldValue !== newValue) { + await this.loadResource(); + } + this.render(); + } + + async loadResource() { + const subject = this.getAttribute('subject'); + if (!subject || this._loading) { + return; + } + + try { + this._loading = true; + this._resource = await store.getResource(subject); + + // Set attributes based on resource properties + + const elements = this._resource.get( + 'https://atomicdata.dev/properties/documents/elements', + ); + if (elements) { + this.setAttribute('elements', elements); + } + + const undefined = this._resource.get( + 'https://atomicdata.dev/properties/name', + ); + if (undefined) { + this.setAttribute('undefined', undefined); + } + } catch (e) { + console.error('Error loading resource:', e); + } finally { + this._loading = false; + this.render(); + } + } + + render() { + if (!this.shadowRoot) return; + + const loading = this._loading; + const subject = this.getAttribute('subject'); + + this.shadowRoot.innerHTML = ` + +
+ +
+ elements: + ${ + this.getAttribute('elements') || '' + } +
+ +
+ undefined: + ${ + this.getAttribute('undefined') || '' + } +
+ +
+ `; + } +} + +customElements.define('atomic-document', documentElement); + +class floatRangePropertyElement extends HTMLElement { + static get observedAttributes() { + return ['subject', 'minFloat', 'maxFloat']; + } + + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + this._resource = null; + this._loading = false; + } + + async connectedCallback() { + this.render(); + await this.loadResource(); + } + + async attributeChangedCallback(name, oldValue, newValue) { + if (name === 'subject' && oldValue !== newValue) { + await this.loadResource(); + } + this.render(); + } + + async loadResource() { + const subject = this.getAttribute('subject'); + if (!subject || this._loading) { + return; + } + + try { + this._loading = true; + this._resource = await store.getResource(subject); + + // Set attributes based on resource properties + + const minFloat = this._resource.get( + 'https://atomicdata.dev/properties/minFloat', + ); + if (minFloat) { + this.setAttribute('minFloat', minFloat); + } + + const maxFloat = this._resource.get( + 'https://atomicdata.dev/properties/maxFloat', + ); + if (maxFloat) { + this.setAttribute('maxFloat', maxFloat); + } + } catch (e) { + console.error('Error loading resource:', e); + } finally { + this._loading = false; + this.render(); + } + } + + render() { + if (!this.shadowRoot) return; + + const loading = this._loading; + const subject = this.getAttribute('subject'); + + this.shadowRoot.innerHTML = ` + +
+ +
+ minFloat: + ${ + this.getAttribute('minFloat') || '' + } +
+ +
+ maxFloat: + ${ + this.getAttribute('maxFloat') || '' + } +
+ +
+ `; + } +} + +customElements.define('atomic-float-range-property', floatRangePropertyElement); + +class folderElement extends HTMLElement { + static get observedAttributes() { + return ['subject', 'undefined', 'displayStyle', 'subResources']; + } + + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + this._resource = null; + this._loading = false; + } + + async connectedCallback() { + this.render(); + await this.loadResource(); + } + + async attributeChangedCallback(name, oldValue, newValue) { + if (name === 'subject' && oldValue !== newValue) { + await this.loadResource(); + } + this.render(); + } + + async loadResource() { + const subject = this.getAttribute('subject'); + if (!subject || this._loading) { + return; + } + + try { + this._loading = true; + this._resource = await store.getResource(subject); + + // Set attributes based on resource properties + + const undefined = this._resource.get( + 'https://atomicdata.dev/properties/name', + ); + if (undefined) { + this.setAttribute('undefined', undefined); + } + + const displayStyle = this._resource.get( + 'https://atomicdata.dev/property/display-style', + ); + if (displayStyle) { + this.setAttribute('displayStyle', displayStyle); + } + + const subResources = this._resource.get( + 'https://atomicdata.dev/properties/subresources', + ); + if (subResources) { + this.setAttribute('subResources', subResources); + } + } catch (e) { + console.error('Error loading resource:', e); + } finally { + this._loading = false; + this.render(); + } + } + + render() { + if (!this.shadowRoot) return; + + const loading = this._loading; + const subject = this.getAttribute('subject'); + + this.shadowRoot.innerHTML = ` + +
+ +
+ undefined: + ${ + this.getAttribute('undefined') || '' + } +
+ +
+ displayStyle: + ${ + this.getAttribute('displayStyle') || '' + } +
+ +
+ subResources: + ${ + this.getAttribute('subResources') || '' + } +
+ +
+ Required: undefined +
+ +
+ Required: displayStyle +
+
+ `; + } +} + +customElements.define('atomic-folder', folderElement); + +class formattedDateElement extends HTMLElement { + static get observedAttributes() { + return ['subject', 'dateFormat']; + } + + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + this._resource = null; + this._loading = false; + } + + async connectedCallback() { + this.render(); + await this.loadResource(); + } + + async attributeChangedCallback(name, oldValue, newValue) { + if (name === 'subject' && oldValue !== newValue) { + await this.loadResource(); + } + this.render(); + } + + async loadResource() { + const subject = this.getAttribute('subject'); + if (!subject || this._loading) { + return; + } + + try { + this._loading = true; + this._resource = await store.getResource(subject); + + // Set attributes based on resource properties + + const dateFormat = this._resource.get( + 'https://atomicdata.dev/properties/dateFormat', + ); + if (dateFormat) { + this.setAttribute('dateFormat', dateFormat); + } + } catch (e) { + console.error('Error loading resource:', e); + } finally { + this._loading = false; + this.render(); + } + } + + render() { + if (!this.shadowRoot) return; + + const loading = this._loading; + const subject = this.getAttribute('subject'); + + this.shadowRoot.innerHTML = ` + +
+ +
+ dateFormat: + ${ + this.getAttribute('dateFormat') || '' + } +
+ +
+ Required: dateFormat +
+
+ `; + } +} + +customElements.define('atomic-formatted-date', formattedDateElement); + +class formattedNumberElement extends HTMLElement { + static get observedAttributes() { + return ['subject', 'numberFormatting', 'decimalPlaces']; + } + + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + this._resource = null; + this._loading = false; + } + + async connectedCallback() { + this.render(); + await this.loadResource(); + } + + async attributeChangedCallback(name, oldValue, newValue) { + if (name === 'subject' && oldValue !== newValue) { + await this.loadResource(); + } + this.render(); + } + + async loadResource() { + const subject = this.getAttribute('subject'); + if (!subject || this._loading) { + return; + } + + try { + this._loading = true; + this._resource = await store.getResource(subject); + + // Set attributes based on resource properties + + const numberFormatting = this._resource.get( + 'https://atomicdata.dev/properties/numberFormatting', + ); + if (numberFormatting) { + this.setAttribute('numberFormatting', numberFormatting); + } + + const decimalPlaces = this._resource.get( + 'https://atomicdata.dev/properties/decimalPlaces', + ); + if (decimalPlaces) { + this.setAttribute('decimalPlaces', decimalPlaces); + } + } catch (e) { + console.error('Error loading resource:', e); + } finally { + this._loading = false; + this.render(); + } + } + + render() { + if (!this.shadowRoot) return; + + const loading = this._loading; + const subject = this.getAttribute('subject'); + + this.shadowRoot.innerHTML = ` + +
+ +
+ numberFormatting: + ${ + this.getAttribute('numberFormatting') || '' + } +
+ +
+ decimalPlaces: + ${ + this.getAttribute('decimalPlaces') || '' + } +
+ +
+ Required: numberFormatting +
+
+ `; + } +} + +customElements.define('atomic-formatted-number', formattedNumberElement); + +class importerElement extends HTMLElement { + static get observedAttributes() { + return ['subject']; + } + + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + this._resource = null; + this._loading = false; + } + + async connectedCallback() { + this.render(); + await this.loadResource(); + } + + async attributeChangedCallback(name, oldValue, newValue) { + if (name === 'subject' && oldValue !== newValue) { + await this.loadResource(); + } + this.render(); + } + + async loadResource() { + const subject = this.getAttribute('subject'); + if (!subject || this._loading) { + return; + } + + try { + this._loading = true; + this._resource = await store.getResource(subject); + + // Set attributes based on resource properties + } catch (e) { + console.error('Error loading resource:', e); + } finally { + this._loading = false; + this.render(); + } + } + + render() { + if (!this.shadowRoot) return; + + const loading = this._loading; + const subject = this.getAttribute('subject'); + + this.shadowRoot.innerHTML = ` + +
+ + +
+ `; + } +} + +customElements.define('atomic-importer', importerElement); + +class messageElement extends HTMLElement { + static get observedAttributes() { + return ['subject', 'undefined', 'undefined']; + } + + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + this._resource = null; + this._loading = false; + } + + async connectedCallback() { + this.render(); + await this.loadResource(); + } + + async attributeChangedCallback(name, oldValue, newValue) { + if (name === 'subject' && oldValue !== newValue) { + await this.loadResource(); + } + this.render(); + } + + async loadResource() { + const subject = this.getAttribute('subject'); + if (!subject || this._loading) { + return; + } + + try { + this._loading = true; + this._resource = await store.getResource(subject); + + // Set attributes based on resource properties + + const undefined = this._resource.get( + 'https://atomicdata.dev/properties/description', + ); + if (undefined) { + this.setAttribute('undefined', undefined); + } + + const undefined = this._resource.get( + 'https://atomicdata.dev/properties/parent', + ); + if (undefined) { + this.setAttribute('undefined', undefined); + } + } catch (e) { + console.error('Error loading resource:', e); + } finally { + this._loading = false; + this.render(); + } + } + + render() { + if (!this.shadowRoot) return; + + const loading = this._loading; + const subject = this.getAttribute('subject'); + + this.shadowRoot.innerHTML = ` + +
+ +
+ undefined: + ${ + this.getAttribute('undefined') || '' + } +
+ +
+ undefined: + ${ + this.getAttribute('undefined') || '' + } +
+ +
+ Required: undefined +
+ +
+ Required: undefined +
+
+ `; + } +} + +customElements.define('atomic-message', messageElement); + +class numberFormatElement extends HTMLElement { + static get observedAttributes() { + return ['subject', 'undefined']; + } + + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + this._resource = null; + this._loading = false; + } + + async connectedCallback() { + this.render(); + await this.loadResource(); + } + + async attributeChangedCallback(name, oldValue, newValue) { + if (name === 'subject' && oldValue !== newValue) { + await this.loadResource(); + } + this.render(); + } + + async loadResource() { + const subject = this.getAttribute('subject'); + if (!subject || this._loading) { + return; + } + + try { + this._loading = true; + this._resource = await store.getResource(subject); + + // Set attributes based on resource properties + + const undefined = this._resource.get( + 'https://atomicdata.dev/properties/shortname', + ); + if (undefined) { + this.setAttribute('undefined', undefined); + } + } catch (e) { + console.error('Error loading resource:', e); + } finally { + this._loading = false; + this.render(); + } + } + + render() { + if (!this.shadowRoot) return; + + const loading = this._loading; + const subject = this.getAttribute('subject'); + + this.shadowRoot.innerHTML = ` + +
+ +
+ undefined: + ${ + this.getAttribute('undefined') || '' + } +
+ +
+ Required: undefined +
+
+ `; + } +} + +customElements.define('atomic-number-format', numberFormatElement); + +class paragraphElement extends HTMLElement { + static get observedAttributes() { + return ['subject', 'undefined', 'undefined']; + } + + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + this._resource = null; + this._loading = false; + } + + async connectedCallback() { + this.render(); + await this.loadResource(); + } + + async attributeChangedCallback(name, oldValue, newValue) { + if (name === 'subject' && oldValue !== newValue) { + await this.loadResource(); + } + this.render(); + } + + async loadResource() { + const subject = this.getAttribute('subject'); + if (!subject || this._loading) { + return; + } + + try { + this._loading = true; + this._resource = await store.getResource(subject); + + // Set attributes based on resource properties + + const undefined = this._resource.get( + 'https://atomicdata.dev/properties/description', + ); + if (undefined) { + this.setAttribute('undefined', undefined); + } + + const undefined = this._resource.get( + 'https://atomicdata.dev/properties/parent', + ); + if (undefined) { + this.setAttribute('undefined', undefined); + } + } catch (e) { + console.error('Error loading resource:', e); + } finally { + this._loading = false; + this.render(); + } + } + + render() { + if (!this.shadowRoot) return; + + const loading = this._loading; + const subject = this.getAttribute('subject'); + + this.shadowRoot.innerHTML = ` + +
+ +
+ undefined: + ${ + this.getAttribute('undefined') || '' + } +
+ +
+ undefined: + ${ + this.getAttribute('undefined') || '' + } +
+ +
+ Required: undefined +
+ +
+ Required: undefined +
+
+ `; + } +} + +customElements.define('atomic-paragraph', paragraphElement); + +class rangePropertyElement extends HTMLElement { + static get observedAttributes() { + return ['subject', 'min', 'max']; + } + + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + this._resource = null; + this._loading = false; + } + + async connectedCallback() { + this.render(); + await this.loadResource(); + } + + async attributeChangedCallback(name, oldValue, newValue) { + if (name === 'subject' && oldValue !== newValue) { + await this.loadResource(); + } + this.render(); + } + + async loadResource() { + const subject = this.getAttribute('subject'); + if (!subject || this._loading) { + return; + } + + try { + this._loading = true; + this._resource = await store.getResource(subject); + + // Set attributes based on resource properties + + const min = this._resource.get('https://atomicdata.dev/properties/min'); + if (min) { + this.setAttribute('min', min); + } + + const max = this._resource.get('https://atomicdata.dev/properties/max'); + if (max) { + this.setAttribute('max', max); + } + } catch (e) { + console.error('Error loading resource:', e); + } finally { + this._loading = false; + this.render(); + } + } + + render() { + if (!this.shadowRoot) return; + + const loading = this._loading; + const subject = this.getAttribute('subject'); + + this.shadowRoot.innerHTML = ` + +
+ +
+ min: + ${this.getAttribute('min') || ''} +
+ +
+ max: + ${this.getAttribute('max') || ''} +
+ +
+ `; + } +} + +customElements.define('atomic-range-property', rangePropertyElement); + +class selectPropertyElement extends HTMLElement { + static get observedAttributes() { + return ['subject', 'undefined', 'max']; + } + + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + this._resource = null; + this._loading = false; + } + + async connectedCallback() { + this.render(); + await this.loadResource(); + } + + async attributeChangedCallback(name, oldValue, newValue) { + if (name === 'subject' && oldValue !== newValue) { + await this.loadResource(); + } + this.render(); + } + + async loadResource() { + const subject = this.getAttribute('subject'); + if (!subject || this._loading) { + return; + } + + try { + this._loading = true; + this._resource = await store.getResource(subject); + + // Set attributes based on resource properties + + const undefined = this._resource.get( + 'https://atomicdata.dev/properties/allowsOnly', + ); + if (undefined) { + this.setAttribute('undefined', undefined); + } + + const max = this._resource.get('https://atomicdata.dev/properties/max'); + if (max) { + this.setAttribute('max', max); + } + } catch (e) { + console.error('Error loading resource:', e); + } finally { + this._loading = false; + this.render(); + } + } + + render() { + if (!this.shadowRoot) return; + + const loading = this._loading; + const subject = this.getAttribute('subject'); + + this.shadowRoot.innerHTML = ` + +
+ +
+ undefined: + ${ + this.getAttribute('undefined') || '' + } +
+ +
+ max: + ${this.getAttribute('max') || ''} +
+ +
+ Required: undefined +
+
+ `; + } +} + +customElements.define('atomic-select-property', selectPropertyElement); + +class tableElement extends HTMLElement { + static get observedAttributes() { + return ['subject', 'undefined', 'undefined']; + } + + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + this._resource = null; + this._loading = false; + } + + async connectedCallback() { + this.render(); + await this.loadResource(); + } + + async attributeChangedCallback(name, oldValue, newValue) { + if (name === 'subject' && oldValue !== newValue) { + await this.loadResource(); + } + this.render(); + } + + async loadResource() { + const subject = this.getAttribute('subject'); + if (!subject || this._loading) { + return; + } + + try { + this._loading = true; + this._resource = await store.getResource(subject); + + // Set attributes based on resource properties + + const undefined = this._resource.get( + 'https://atomicdata.dev/properties/classtype', + ); + if (undefined) { + this.setAttribute('undefined', undefined); + } + + const undefined = this._resource.get( + 'https://atomicdata.dev/properties/name', + ); + if (undefined) { + this.setAttribute('undefined', undefined); + } + } catch (e) { + console.error('Error loading resource:', e); + } finally { + this._loading = false; + this.render(); + } + } + + render() { + if (!this.shadowRoot) return; + + const loading = this._loading; + const subject = this.getAttribute('subject'); + + this.shadowRoot.innerHTML = ` + +
+ +
+ undefined: + ${ + this.getAttribute('undefined') || '' + } +
+ +
+ undefined: + ${ + this.getAttribute('undefined') || '' + } +
+ +
+ Required: undefined +
+ +
+ Required: undefined +
+
+ `; + } +} + +customElements.define('atomic-table', tableElement); + +class tagElement extends HTMLElement { + static get observedAttributes() { + return ['subject', 'undefined', 'color', 'emoji']; + } + + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + this._resource = null; + this._loading = false; + } + + async connectedCallback() { + this.render(); + await this.loadResource(); + } + + async attributeChangedCallback(name, oldValue, newValue) { + if (name === 'subject' && oldValue !== newValue) { + await this.loadResource(); + } + this.render(); + } + + async loadResource() { + const subject = this.getAttribute('subject'); + if (!subject || this._loading) { + return; + } + + try { + this._loading = true; + this._resource = await store.getResource(subject); + + // Set attributes based on resource properties + + const undefined = this._resource.get( + 'https://atomicdata.dev/properties/shortname', + ); + if (undefined) { + this.setAttribute('undefined', undefined); + } + + const color = this._resource.get( + 'https://atomicdata.dev/properties/color', + ); + if (color) { + this.setAttribute('color', color); + } + + const emoji = this._resource.get( + 'https://atomicdata.dev/properties/emoji', + ); + if (emoji) { + this.setAttribute('emoji', emoji); + } + } catch (e) { + console.error('Error loading resource:', e); + } finally { + this._loading = false; + this.render(); + } + } + + render() { + if (!this.shadowRoot) return; + + const loading = this._loading; + const subject = this.getAttribute('subject'); + + this.shadowRoot.innerHTML = ` + +
+ +
+ undefined: + ${ + this.getAttribute('undefined') || '' + } +
+ +
+ color: + ${ + this.getAttribute('color') || '' + } +
+ +
+ emoji: + ${ + this.getAttribute('emoji') || '' + } +
+ +
+ Required: undefined +
+
+ `; + } +} + +customElements.define('atomic-tag', tagElement); + +class templateElement extends HTMLElement { + static get observedAttributes() { + return ['subject', 'undefined', 'undefined', 'image', 'resources']; + } + + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + this._resource = null; + this._loading = false; + } + + async connectedCallback() { + this.render(); + await this.loadResource(); + } + + async attributeChangedCallback(name, oldValue, newValue) { + if (name === 'subject' && oldValue !== newValue) { + await this.loadResource(); + } + this.render(); + } + + async loadResource() { + const subject = this.getAttribute('subject'); + if (!subject || this._loading) { + return; + } + + try { + this._loading = true; + this._resource = await store.getResource(subject); + + // Set attributes based on resource properties + + const undefined = this._resource.get( + 'https://atomicdata.dev/properties/name', + ); + if (undefined) { + this.setAttribute('undefined', undefined); + } + + const undefined = this._resource.get( + 'https://atomicdata.dev/properties/description', + ); + if (undefined) { + this.setAttribute('undefined', undefined); + } + + const image = this._resource.get( + 'https://atomicdata.dev/ontology/data-browser/property/image', + ); + if (image) { + this.setAttribute('image', image); + } + + const resources = this._resource.get( + 'https://atomicdata.dev/ontology/data-browser/property/resources', + ); + if (resources) { + this.setAttribute('resources', resources); + } + } catch (e) { + console.error('Error loading resource:', e); + } finally { + this._loading = false; + this.render(); + } + } + + render() { + if (!this.shadowRoot) return; + + const loading = this._loading; + const subject = this.getAttribute('subject'); + + this.shadowRoot.innerHTML = ` + +
+ +
+ undefined: + ${ + this.getAttribute('undefined') || '' + } +
+ +
+ undefined: + ${ + this.getAttribute('undefined') || '' + } +
+ +
+ image: + ${ + this.getAttribute('image') || '' + } +
+ +
+ resources: + ${ + this.getAttribute('resources') || '' + } +
+ +
+ Required: undefined +
+ +
+ Required: undefined +
+ +
+ Required: image +
+ +
+ Required: resources +
+
+ `; + } +} + +customElements.define('atomic-template', templateElement); + +declare module '@tomic/lib' { + interface Classes { + [dataBrowser.classes.article]: { + requires: + | BaseProps + | 'https://atomicdata.dev/properties/description' + | 'https://atomicdata.dev/properties/name'; + recommends: + | typeof dataBrowser.properties.tags + | typeof dataBrowser.properties.publishedAt; + }; + [dataBrowser.classes.bookmark]: { + requires: + | BaseProps + | 'https://atomicdata.dev/properties/name' + | typeof dataBrowser.properties.url; + recommends: + | typeof dataBrowser.properties.preview + | 'https://atomicdata.dev/properties/description' + | typeof dataBrowser.properties.imageUrl; + }; + [dataBrowser.classes.chatroom]: { + requires: BaseProps | 'https://atomicdata.dev/properties/name'; + recommends: typeof dataBrowser.properties.messages; + }; + [dataBrowser.classes.currencyProperty]: { + requires: BaseProps | typeof dataBrowser.properties.currency; + recommends: never; + }; + [dataBrowser.classes.dateFormat]: { + requires: BaseProps | 'https://atomicdata.dev/properties/shortname'; + recommends: never; + }; + [dataBrowser.classes.displayStyle]: { + requires: BaseProps | 'https://atomicdata.dev/properties/name'; + recommends: never; + }; + [dataBrowser.classes.document]: { + requires: BaseProps; + recommends: + | typeof dataBrowser.properties.elements + | 'https://atomicdata.dev/properties/name'; + }; + [dataBrowser.classes.floatRangeProperty]: { + requires: BaseProps; + recommends: + | typeof dataBrowser.properties.minFloat + | typeof dataBrowser.properties.maxFloat; + }; + [dataBrowser.classes.folder]: { + requires: + | BaseProps + | 'https://atomicdata.dev/properties/name' + | typeof dataBrowser.properties.displayStyle; + recommends: typeof dataBrowser.properties.subResources; + }; + [dataBrowser.classes.formattedDate]: { + requires: BaseProps | typeof dataBrowser.properties.dateFormat; + recommends: never; + }; + [dataBrowser.classes.formattedNumber]: { + requires: BaseProps | typeof dataBrowser.properties.numberFormatting; + recommends: typeof dataBrowser.properties.decimalPlaces; + }; + [dataBrowser.classes.importer]: { + requires: BaseProps; + recommends: never; + }; + [dataBrowser.classes.message]: { + requires: + | BaseProps + | 'https://atomicdata.dev/properties/description' + | 'https://atomicdata.dev/properties/parent'; + recommends: never; + }; + [dataBrowser.classes.numberFormat]: { + requires: BaseProps | 'https://atomicdata.dev/properties/shortname'; + recommends: never; + }; + [dataBrowser.classes.paragraph]: { + requires: + | BaseProps + | 'https://atomicdata.dev/properties/description' + | 'https://atomicdata.dev/properties/parent'; + recommends: never; + }; + [dataBrowser.classes.rangeProperty]: { + requires: BaseProps; + recommends: + | typeof dataBrowser.properties.min + | typeof dataBrowser.properties.max; + }; + [dataBrowser.classes.selectProperty]: { + requires: BaseProps | 'https://atomicdata.dev/properties/allowsOnly'; + recommends: typeof dataBrowser.properties.max; + }; + [dataBrowser.classes.table]: { + requires: + | BaseProps + | 'https://atomicdata.dev/properties/classtype' + | 'https://atomicdata.dev/properties/name'; + recommends: never; + }; + [dataBrowser.classes.tag]: { + requires: BaseProps | 'https://atomicdata.dev/properties/shortname'; + recommends: + | typeof dataBrowser.properties.color + | typeof dataBrowser.properties.emoji; + }; + [dataBrowser.classes.template]: { + requires: + | BaseProps + | 'https://atomicdata.dev/properties/name' + | 'https://atomicdata.dev/properties/description' + | typeof dataBrowser.properties.image + | typeof dataBrowser.properties.resources; + recommends: never; + }; + } + + interface PropTypeMapping { + [dataBrowser.properties.color]: string; + [dataBrowser.properties.currency]: string; + [dataBrowser.properties.customNodePositioning]: string; + [dataBrowser.properties.dateFormat]: string; + [dataBrowser.properties.decimalPlaces]: number; + [dataBrowser.properties.displayStyle]: string; + [dataBrowser.properties.elements]: string[]; + [dataBrowser.properties.emoji]: string; + [dataBrowser.properties.image]: string; + [dataBrowser.properties.imageUrl]: string; + [dataBrowser.properties.max]: number; + [dataBrowser.properties.maxFloat]: number; + [dataBrowser.properties.messages]: string[]; + [dataBrowser.properties.min]: number; + [dataBrowser.properties.minFloat]: number; + [dataBrowser.properties.nextPage]: string; + [dataBrowser.properties.numberFormatting]: string; + [dataBrowser.properties.preview]: string; + [dataBrowser.properties.publishedAt]: number; + [dataBrowser.properties.replyTo]: string; + [dataBrowser.properties.resources]: string[]; + [dataBrowser.properties.subResources]: string[]; + [dataBrowser.properties.tableColumnWidths]: string; + [dataBrowser.properties.tags]: string[]; + [dataBrowser.properties.url]: string; + } + + interface PropSubjectToNameMapping { + [dataBrowser.properties.color]: 'color'; + [dataBrowser.properties.currency]: 'currency'; + [dataBrowser.properties.customNodePositioning]: 'customNodePositioning'; + [dataBrowser.properties.dateFormat]: 'dateFormat'; + [dataBrowser.properties.decimalPlaces]: 'decimalPlaces'; + [dataBrowser.properties.displayStyle]: 'displayStyle'; + [dataBrowser.properties.elements]: 'elements'; + [dataBrowser.properties.emoji]: 'emoji'; + [dataBrowser.properties.image]: 'image'; + [dataBrowser.properties.imageUrl]: 'imageUrl'; + [dataBrowser.properties.max]: 'max'; + [dataBrowser.properties.maxFloat]: 'maxFloat'; + [dataBrowser.properties.messages]: 'messages'; + [dataBrowser.properties.min]: 'min'; + [dataBrowser.properties.minFloat]: 'minFloat'; + [dataBrowser.properties.nextPage]: 'nextPage'; + [dataBrowser.properties.numberFormatting]: 'numberFormatting'; + [dataBrowser.properties.preview]: 'preview'; + [dataBrowser.properties.publishedAt]: 'publishedAt'; + [dataBrowser.properties.replyTo]: 'replyTo'; + [dataBrowser.properties.resources]: 'resources'; + [dataBrowser.properties.subResources]: 'subResources'; + [dataBrowser.properties.tableColumnWidths]: 'tableColumnWidths'; + [dataBrowser.properties.tags]: 'tags'; + [dataBrowser.properties.url]: 'url'; + } +} diff --git a/browser/cli/src/ontologies/index.ts b/browser/cli/src/ontologies/index.ts new file mode 100644 index 000000000..3df156cef --- /dev/null +++ b/browser/cli/src/ontologies/index.ts @@ -0,0 +1,11 @@ +/* ----------------------------------- + * GENERATED WITH @tomic/cli + * -------------------------------- */ + +import { registerOntologies } from '@tomic/lib'; + +import { dataBrowser } from './dataBrowser.js'; + +export function initOntologies(): void { + registerOntologies(dataBrowser); +} From 20db8a769964d80845adf341fcc0ab4239de5d00 Mon Sep 17 00:00:00 2001 From: Alex Mikhalev Date: Sat, 23 Nov 2024 18:57:46 +0000 Subject: [PATCH 2/2] Minimal path example --- lib/examples/try_path.rs | 63 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 lib/examples/try_path.rs diff --git a/lib/examples/try_path.rs b/lib/examples/try_path.rs new file mode 100644 index 000000000..933f6d355 --- /dev/null +++ b/lib/examples/try_path.rs @@ -0,0 +1,63 @@ +use atomic_lib::errors::AtomicResult; +use atomic_lib::{agents::ForAgent, Store, Storelike}; + +fn main() -> AtomicResult<()> { + // Initialize a new store and populate with default data + let store = Store::init()?; + store.populate()?; + + // Example paths to query + let paths = vec![ + // Get a Class and its description + "https://atomicdata.dev/classes/Agent description", + // Get all required properties for the Agent class + "https://atomicdata.dev/classes/Agent requires", + // Get the shortname of a Property + "https://atomicdata.dev/properties/description shortname", + ]; + + println!("Querying paths in Atomic Data store:\n"); + + for path_str in paths { + println!("Path: {}", path_str); + + // Get the path result + match store.get_path( + path_str, + None, // No mapping needed for these examples + &ForAgent::Sudo, // Using sudo rights for this example + )? { + atomic_lib::storelike::PathReturn::Subject(subject) => { + // If the path returns a full resource + let resource = store.get_resource_extended(&subject, false, &ForAgent::Sudo)?; + println!("Found resource: {}", resource.get_subject()); + + // Print some basic properties if they exist + if let Ok(shortname) = resource.get_shortname("shortname", &store) { + println!("Shortname: {}", shortname); + } + if let Ok(description) = resource.get_shortname("description", &store) { + println!("Description: {}", description); + } + } + atomic_lib::storelike::PathReturn::Atom(atom) => { + // If the path returns a single value + println!("Found value: {}", atom.value); + } + } + println!("\n---\n"); + } + + // Example of using paths to traverse nested data + let nested_path = "https://atomicdata.dev/classes/Class requires 0 shortname"; + println!("Querying nested path: {}", nested_path); + + match store.get_path(nested_path, None, &ForAgent::Sudo)? { + atomic_lib::storelike::PathReturn::Atom(atom) => { + println!("First required property shortname: {}", atom.value); + } + _ => println!("Unexpected return type"), + } + + Ok(()) +}