@aglyn/shared-data-types 1.0.0-beta.143

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,345 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2023 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /**
18
+ * (D)Document-(o)oriented (D)Database (DoD)
19
+ *
20
+ * A document-oriented database, or DoD, or document
21
+ * store, is a data storage structure designed for
22
+ * storing, retrieving and managing document-oriented
23
+ * information, also known as semi-structured data.
24
+ *
25
+ * Each document contains a set of key-value pairs.
26
+ * All documents must be stored in collections.
27
+ *
28
+ * Documents can contain literal fields such as
29
+ * text/strings, numbers, or booleans, and secondly
30
+ * nestable fields such as arrays or mapped objects.
31
+ *
32
+ * The special sauce here which deviates from a
33
+ * traditional DoD is the overlaid design patterns
34
+ * which provide the outlines for capabilities such
35
+ * as relational- and model-driven
36
+ *
37
+ * @module dod
38
+ */
39
+ /** Primary key */
40
+ export type PKey = string;
41
+ /** Foreign key */
42
+ export type FKey = string;
43
+ /** Alternate key */
44
+ export type AKey = string;
45
+ /** Tuple with exactly two nodes */
46
+ export interface TupleLn2<T1, T2 = T1> extends Array<T1 | T2> {
47
+ 0: T1;
48
+ 1: T2;
49
+ length: 2;
50
+ }
51
+ /** Tuple with a minimum of one nodes */
52
+ interface TupleMinLn1<T> extends Array<T> {
53
+ 0: T;
54
+ }
55
+ /** Tuple with a minimum of two nodes */
56
+ interface TupleMinLn2<T1, T2 = T1> extends TupleMinLn1<T1 | T2> {
57
+ 0: T1;
58
+ 1: T2;
59
+ }
60
+ /**
61
+ * Nominal Type hack to declare a typeof type for
62
+ * a unique symbol. This is because `unique symbol`
63
+ * can only be typed from a const.
64
+ *
65
+ * @see https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#unique-symbol
66
+ */
67
+ declare const NominalSymbol: unique symbol;
68
+ export type UniqSym = typeof NominalSymbol;
69
+ /**
70
+ * Describes relationship design patterns to
71
+ * outline a RDBMS equivalent
72
+ */
73
+ export declare namespace Relation {
74
+ /**
75
+ * A associative lookup for unnatural/extrinsic
76
+ * Many-to-Many relationship.
77
+ *
78
+ * Note: intrinsic 2-way relations should live within
79
+ * both documents and not use an extra query/join for
80
+ * the lookup! However, a rare scenario that it is too
81
+ * large, you may store the most recent (n) items in
82
+ * the two documents and use the lookup for the rest.
83
+ *
84
+ * Consider the following 2-way relationship:
85
+ * group1 = [user1, user3]
86
+ * group2 = [user1, user2]
87
+ * group3 = [user2, user3]
88
+ * user1 = [group1, group2]
89
+ * user2 = [group2, group3]
90
+ * user3 = [group1, group3]
91
+ *
92
+ * That would be displayed in an associative as follows:
93
+ * AK1 = [group1, user1]
94
+ * AK2 = [group1, user3]
95
+ * AK3 = [group2, user1]
96
+ * AK4 = [group2, user2]
97
+ * AK5 = [group3, user2]
98
+ * AK6 = [group3, user3]
99
+ */
100
+ type Associative = TupleLn2<FKey>;
101
+ /**
102
+ * Similar to an associative relation but rather to
103
+ * find many associations
104
+ *
105
+ * e.g. Invoice, Product, User lookups
106
+ * AK1 = [invoiceId, productId, userId]
107
+ */
108
+ type Lookup = TupleMinLn2<FKey>;
109
+ }
110
+ /** Field Type */
111
+ export declare namespace FT {
112
+ type Bool = boolean;
113
+ type Bytes = Uint8Array | string;
114
+ type Timestamp = number;
115
+ type Float = number;
116
+ type Int32 = number;
117
+ type Int64 = number;
118
+ type Null = null;
119
+ type Text = string;
120
+ type Coordinates = Record<'longitude' | 'latitude', number>;
121
+ type Map = Dictionary;
122
+ type Sorted<T = any> = T extends any[] ? never : T[];
123
+ type Nestable = Map | Sorted<any>;
124
+ type Any<T = any> = Sorted<T> | Bool | Bytes | Timestamp | Float | Coordinates | Int32 | Int64 | Map | Null | Text;
125
+ namespace Tag {
126
+ const bool = "bool";
127
+ const bytes = "bytes";
128
+ const timestamp = "timestamp";
129
+ const float = "float";
130
+ const int32 = "int32";
131
+ const int64 = "int64";
132
+ const nil = "nil";
133
+ const text = "text";
134
+ const coordinates = "coordinates";
135
+ const map = "map";
136
+ const sorted = "sorted";
137
+ const all: string[];
138
+ type T = typeof Tag.bool | typeof Tag.bytes | typeof Tag.timestamp | typeof Tag.float | typeof Tag.int32 | typeof Tag.int64 | typeof Tag.nil | typeof Tag.text | typeof Tag.coordinates | typeof Tag.map | typeof Tag.sorted;
139
+ }
140
+ /** Match Type from Tag symbol */
141
+ type TypeFromTag<Kind extends Tag.T> = Kind extends typeof Tag.bool ? Bool : Kind extends typeof Tag.bytes ? Uint8Array : Kind extends typeof Tag.timestamp ? Timestamp : Kind extends typeof Tag.float ? Float : Kind extends typeof Tag.int32 ? Int32 : Kind extends typeof Tag.int64 ? Int64 : Kind extends typeof Tag.nil ? Null : Kind extends typeof Tag.text ? Text : Kind extends typeof Tag.coordinates ? Coordinates : Kind extends typeof Tag.map ? Map : Kind extends typeof Tag.sorted ? Sorted<any> : never;
142
+ }
143
+ /** Field */
144
+ export type FieldValueType<T = any> = FT.Any<T>;
145
+ /** Document */
146
+ export type DocumentType<F extends FieldValueType = any> = {
147
+ [fieldId: string]: F;
148
+ };
149
+ /** Collection */
150
+ export type CollectionType = {
151
+ [documentId: string]: DocumentType;
152
+ };
153
+ /** Database */
154
+ export type DatabaseType = {
155
+ [collectionId: string]: CollectionType;
156
+ };
157
+ /** Cluster */
158
+ export type ClusterType = {
159
+ [databaseId: string]: DatabaseType;
160
+ };
161
+ /**
162
+ * Outlines schemas for entity types (e.g., field, doc, collection)
163
+ */
164
+ export declare namespace Schema {
165
+ /**
166
+ * Name fields
167
+ */
168
+ type Name = {
169
+ singular?: FT.Text;
170
+ plural?: FT.Text;
171
+ };
172
+ /**
173
+ * Interface properties for a timestamp lifecycle
174
+ *
175
+ * @export
176
+ * @interface StampedLifecycle
177
+ */
178
+ type StampedLifecycle = Partial<Record<StampedKeys, FT.Timestamp>>;
179
+ type StampedKeys = 'created' | 'updated' | 'delete';
180
+ /** Just a boxed name field */
181
+ interface NamedField {
182
+ name: Name;
183
+ }
184
+ /**
185
+ * Describes the meta object for a field instance
186
+ */
187
+ interface FieldDefinition extends NamedField {
188
+ type: FT.Tag.T;
189
+ description?: FT.Text;
190
+ }
191
+ /**
192
+ * Outlines the fields to be designated for a new
193
+ * document instance within the parent collection
194
+ */
195
+ type ModelFields = {
196
+ [fieldId: string]: FieldDefinition;
197
+ };
198
+ /**
199
+ * Describes a collection of documents, the fields
200
+ * property describes the fields of any document an
201
+ * instance of the collection.
202
+ */
203
+ interface CollectionModel extends DocumentType, StampedLifecycle, NamedField {
204
+ fields: ModelFields;
205
+ }
206
+ /**
207
+ * Describes a collection of documents, each document
208
+ * only describes another collection e.g. the meta
209
+ */
210
+ type CollectionModels = CollectionType & {
211
+ [collectionIdAsDocumentId: string]: CollectionModel;
212
+ };
213
+ /**
214
+ * =======================================================
215
+ */
216
+ /**
217
+ * The actual collection instance of a collection meta
218
+ */
219
+ type CollectionInstance<T extends CollectionModel> = CollectionType & {
220
+ [documentId: string]: DocumentType<FT.TypeFromTag<T['fields'][string]['type']>>;
221
+ };
222
+ /**
223
+ * Just simply a database of collections
224
+ */
225
+ type DatabaseCollections<C extends CollectionModels> = DatabaseType & {
226
+ [CID in keyof C]: CollectionInstance<C[CID]>;
227
+ };
228
+ }
229
+ export declare namespace Ref {
230
+ interface Base<S = any> {
231
+ id: PKey;
232
+ schema: S;
233
+ }
234
+ /**
235
+ * =======================================================
236
+ */
237
+ type Field<S extends Schema.FieldDefinition> = FT.TypeFromTag<S['type']>;
238
+ /**
239
+ * =======================================================
240
+ */
241
+ type DocumentFields<S extends Schema.ModelFields> = {
242
+ [K in keyof S]: Field<S[K]>;
243
+ };
244
+ type Document<S extends Schema.ModelFields> = DocumentFields<S>;
245
+ /**
246
+ * =======================================================
247
+ */
248
+ type CollectionDocuments<S extends Schema.CollectionModel> = {
249
+ [documentId: string]: Document<S['fields']>;
250
+ };
251
+ type Collection<S extends Schema.CollectionModel> = CollectionDocuments<S>;
252
+ /**
253
+ * =======================================================
254
+ */
255
+ interface Database {
256
+ schemas: Schema.CollectionModels;
257
+ instances: Schema.DatabaseCollections<this['schemas']>;
258
+ }
259
+ }
260
+ /**
261
+ * Evaluation kinds
262
+ */
263
+ export declare enum Eval {
264
+ Required = "r6d",
265
+ Regex = "r3x"
266
+ }
267
+ /**
268
+ * Property name index signatures
269
+ */
270
+ export declare const Sig: {
271
+ Field: string;
272
+ Fields: string;
273
+ Document: string;
274
+ Documents: string;
275
+ Collection: string;
276
+ Collections: string;
277
+ Subcollection: string;
278
+ Subcollections: string;
279
+ Model: string;
280
+ Models: string;
281
+ Blueprint: string;
282
+ Blueprints: string;
283
+ Entry: string;
284
+ Entries: string;
285
+ Id: string;
286
+ Name: string;
287
+ Kind: string;
288
+ Type: string;
289
+ Value: string;
290
+ Created: string;
291
+ Updated: string;
292
+ Deleted: string;
293
+ };
294
+ /**
295
+ * Friendly-text/display-names of local names or
296
+ *
297
+ * TODO: i18n
298
+ */
299
+ export declare const lbl: {
300
+ /** Entity type fields */
301
+ [Sig.Field]: string;
302
+ [Sig.Fields]: string;
303
+ [Sig.Document]: string;
304
+ [Sig.Documents]: string;
305
+ [Sig.Collection]: string;
306
+ [Sig.Collections]: string;
307
+ [Sig.Subcollection]: string;
308
+ [Sig.Subcollections]: string;
309
+ /** Instance fields */
310
+ [Sig.Blueprint]: string;
311
+ [Sig.Blueprints]: string;
312
+ [Sig.Model]: string;
313
+ [Sig.Models]: string;
314
+ [Sig.Entry]: string;
315
+ [Sig.Entries]: string;
316
+ /** Meta fields */
317
+ [Sig.Id]: string;
318
+ [Sig.Name]: string;
319
+ [Sig.Kind]: string;
320
+ [Sig.Type]: string;
321
+ [Sig.Value]: string;
322
+ /** Timestamp fields */
323
+ [Sig.Created]: string;
324
+ [Sig.Updated]: string;
325
+ [Sig.Deleted]: string;
326
+ /** Field Data Types */
327
+ bool: string;
328
+ bytes: string;
329
+ timestamp: string;
330
+ float: string;
331
+ int32: string;
332
+ int64: string;
333
+ nil: string;
334
+ text: string;
335
+ coordinates: string;
336
+ map: string;
337
+ sorted: string;
338
+ };
339
+ /** Contextual persistence types */
340
+ export declare enum Persistance {
341
+ NONE = "NONE",
342
+ SESSION = "SESSION",
343
+ LOCAL = "LOCAL"
344
+ }
345
+ export {};
package/src/lib/dod.js ADDED
@@ -0,0 +1,150 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2023 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ /*
17
+ * NOTE (AGL-177): this file is the 2023-era type-level design doc. The
18
+ * RUNTIME source of truth for dataset models now lives in
19
+ * `libs/aglyn/src/lib/app-utils/dataset-models.ts` — extend that module,
20
+ * not this one.
21
+ */ /**
22
+ * (D)Document-(o)oriented (D)Database (DoD)
23
+ *
24
+ * A document-oriented database, or DoD, or document
25
+ * store, is a data storage structure designed for
26
+ * storing, retrieving and managing document-oriented
27
+ * information, also known as semi-structured data.
28
+ *
29
+ * Each document contains a set of key-value pairs.
30
+ * All documents must be stored in collections.
31
+ *
32
+ * Documents can contain literal fields such as
33
+ * text/strings, numbers, or booleans, and secondly
34
+ * nestable fields such as arrays or mapped objects.
35
+ *
36
+ * The special sauce here which deviates from a
37
+ * traditional DoD is the overlaid design patterns
38
+ * which provide the outlines for capabilities such
39
+ * as relational- and model-driven
40
+ *
41
+ * @module dod
42
+ */ /** Primary key */ (function(FT) {
43
+ (function(Tag) {
44
+ Tag.bool = 'bool';
45
+ Tag.bytes = 'bytes';
46
+ Tag.timestamp = 'timestamp';
47
+ Tag.float = 'float';
48
+ Tag.int32 = 'int32';
49
+ Tag.int64 = 'int64';
50
+ Tag.nil = 'nil';
51
+ Tag.text = 'text';
52
+ Tag.coordinates = 'coordinates';
53
+ Tag.map = 'map';
54
+ Tag.sorted = 'sorted';
55
+ Tag.all = [
56
+ FT.Tag.bool,
57
+ FT.Tag.bytes,
58
+ FT.Tag.timestamp,
59
+ FT.Tag.float,
60
+ FT.Tag.int32,
61
+ FT.Tag.int64,
62
+ FT.Tag.nil,
63
+ FT.Tag.text,
64
+ FT.Tag.coordinates,
65
+ FT.Tag.map,
66
+ FT.Tag.sorted
67
+ ];
68
+ })(FT.Tag || (FT.Tag = {}));
69
+ })(FT || (FT = {}));
70
+ /**
71
+ * Evaluation kinds
72
+ */ export var Eval = /*#__PURE__*/ function(Eval) {
73
+ Eval["Required"] = "r6d";
74
+ Eval["Regex"] = "r3x";
75
+ return Eval;
76
+ }({});
77
+ /**
78
+ * Property name index signatures
79
+ */ export const Sig = {
80
+ Field: 'field',
81
+ Fields: 'fields',
82
+ Document: 'document',
83
+ Documents: 'documents',
84
+ Collection: 'collection',
85
+ Collections: 'collections',
86
+ Subcollection: 'subcollection',
87
+ Subcollections: 'subcollections',
88
+ Model: 'model',
89
+ Models: 'models',
90
+ Blueprint: 'blueprint',
91
+ Blueprints: 'blueprints',
92
+ Entry: 'entry',
93
+ Entries: 'entries',
94
+ Id: 'id',
95
+ Name: 'name',
96
+ Kind: 'kind',
97
+ Type: 'type',
98
+ Value: 'value',
99
+ Created: 'created',
100
+ Updated: 'updated',
101
+ Deleted: 'deleted'
102
+ };
103
+ /**
104
+ * Friendly-text/display-names of local names or
105
+ *
106
+ * TODO: i18n
107
+ */ export const lbl = {
108
+ /** Field Data Types */ [FT.Tag.bool]: 'True/False',
109
+ [FT.Tag.bytes]: 'Bytes',
110
+ [FT.Tag.timestamp]: 'Date/Time',
111
+ [FT.Tag.float]: 'Decimal',
112
+ [FT.Tag.int32]: 'Number',
113
+ [FT.Tag.int64]: 'Large Number',
114
+ [FT.Tag.nil]: 'Null',
115
+ [FT.Tag.text]: 'Text',
116
+ [FT.Tag.coordinates]: 'Coordinates (lat/lon)',
117
+ [FT.Tag.map]: 'Map',
118
+ [FT.Tag.sorted]: 'Sorted',
119
+ /** Entity type fields */ [Sig.Field]: 'Field',
120
+ [Sig.Fields]: 'Fields',
121
+ [Sig.Document]: 'Document',
122
+ [Sig.Documents]: 'Documents',
123
+ [Sig.Collection]: 'Collection',
124
+ [Sig.Collections]: 'Collections',
125
+ [Sig.Subcollection]: 'Subcollection',
126
+ [Sig.Subcollections]: 'Subcollections',
127
+ /** Instance fields */ [Sig.Blueprint]: 'Blueprint',
128
+ [Sig.Blueprints]: 'Blueprints',
129
+ [Sig.Model]: 'Model',
130
+ [Sig.Models]: 'Models',
131
+ [Sig.Entry]: 'Entry',
132
+ [Sig.Entries]: 'Entries',
133
+ /** Meta fields */ [Sig.Id]: 'Unique ID',
134
+ [Sig.Name]: 'Display Name',
135
+ [Sig.Kind]: 'Kind',
136
+ [Sig.Type]: 'Type',
137
+ [Sig.Value]: 'Value',
138
+ /** Timestamp fields */ [Sig.Created]: 'Created At',
139
+ [Sig.Updated]: 'Updated At',
140
+ [Sig.Deleted]: 'Deleted At'
141
+ };
142
+ /** Contextual persistence types */ export var Persistance = /*#__PURE__*/ function(Persistance) {
143
+ Persistance["NONE"] = "NONE";
144
+ Persistance["SESSION"] = "SESSION";
145
+ Persistance["LOCAL"] = "LOCAL";
146
+ return Persistance;
147
+ }({});
148
+ export var FT;
149
+
150
+ //# sourceMappingURL=dod.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/shared/data/types/src/lib/dod.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2023 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * NOTE (AGL-177): this file is the 2023-era type-level design doc. The\n * RUNTIME source of truth for dataset models now lives in\n * `libs/aglyn/src/lib/app-utils/dataset-models.ts` — extend that module,\n * not this one.\n */\n\n/**\n * (D)Document-(o)oriented (D)Database (DoD)\n *\n * A document-oriented database, or DoD, or document\n * store, is a data storage structure designed for\n * storing, retrieving and managing document-oriented\n * information, also known as semi-structured data.\n *\n * Each document contains a set of key-value pairs.\n * All documents must be stored in collections.\n *\n * Documents can contain literal fields such as\n * text/strings, numbers, or booleans, and secondly\n * nestable fields such as arrays or mapped objects.\n *\n * The special sauce here which deviates from a\n * traditional DoD is the overlaid design patterns\n * which provide the outlines for capabilities such\n * as relational- and model-driven\n *\n * @module dod\n */\n\n/** Primary key */\nexport type PKey = string\n/** Foreign key */\nexport type FKey = string\n/** Alternate key */\nexport type AKey = string\n\n/** Tuple with exactly two nodes */\nexport interface TupleLn2<T1, T2 = T1> extends Array<T1 | T2> {\n 0: T1\n 1: T2\n length: 2 // using the numeric literal type '2'\n}\n\n/** Tuple with a minimum of one nodes */\ninterface TupleMinLn1<T> extends Array<T> {\n 0: T\n}\n\n/** Tuple with a minimum of two nodes */\ninterface TupleMinLn2<T1, T2 = T1> extends TupleMinLn1<T1 | T2> {\n 0: T1\n 1: T2\n}\n\n/**\n * Nominal Type hack to declare a typeof type for\n * a unique symbol. This is because `unique symbol`\n * can only be typed from a const.\n *\n * @see https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#unique-symbol\n */\ndeclare const NominalSymbol: unique symbol\nexport type UniqSym = typeof NominalSymbol\n\n/**\n * Describes relationship design patterns to\n * outline a RDBMS equivalent\n */\nexport namespace Relation {\n /**\n * A associative lookup for unnatural/extrinsic\n * Many-to-Many relationship.\n *\n * Note: intrinsic 2-way relations should live within\n * both documents and not use an extra query/join for\n * the lookup! However, a rare scenario that it is too\n * large, you may store the most recent (n) items in\n * the two documents and use the lookup for the rest.\n *\n * Consider the following 2-way relationship:\n * group1 = [user1, user3]\n * group2 = [user1, user2]\n * group3 = [user2, user3]\n * user1 = [group1, group2]\n * user2 = [group2, group3]\n * user3 = [group1, group3]\n *\n * That would be displayed in an associative as follows:\n * AK1 = [group1, user1]\n * AK2 = [group1, user3]\n * AK3 = [group2, user1]\n * AK4 = [group2, user2]\n * AK5 = [group3, user2]\n * AK6 = [group3, user3]\n */\n export type Associative = TupleLn2<FKey>\n\n /**\n * Similar to an associative relation but rather to\n * find many associations\n *\n * e.g. Invoice, Product, User lookups\n * AK1 = [invoiceId, productId, userId]\n */\n export type Lookup = TupleMinLn2<FKey>\n}\n\n/** Field Type */\nexport namespace FT {\n export type Bool = boolean\n export type Bytes = Uint8Array | string\n export type Timestamp = number\n export type Float = number\n export type Int32 = number\n export type Int64 = number\n export type Null = null\n export type Text = string\n export type Coordinates = Record<'longitude' | 'latitude', number>\n export type Map = Dictionary\n export type Sorted<T = any> = T extends any[] ? never : T[]\n\n export type Nestable = Map | Sorted<any>\n\n export type Any<T = any> =\n | Sorted<T>\n | Bool\n | Bytes\n | Timestamp\n | Float\n | Coordinates\n | Int32\n | Int64\n | Map\n | Null\n | Text\n\n export namespace Tag {\n export const bool = 'bool'\n export const bytes = 'bytes'\n export const timestamp = 'timestamp'\n export const float = 'float'\n export const int32 = 'int32'\n export const int64 = 'int64'\n export const nil = 'nil'\n export const text = 'text'\n export const coordinates = 'coordinates'\n export const map = 'map'\n export const sorted = 'sorted'\n\n export const all = [\n Tag.bool,\n Tag.bytes,\n Tag.timestamp,\n Tag.float,\n Tag.int32,\n Tag.int64,\n Tag.nil,\n Tag.text,\n Tag.coordinates,\n Tag.map,\n Tag.sorted,\n ]\n\n export type T =\n | typeof Tag.bool\n | typeof Tag.bytes\n | typeof Tag.timestamp\n | typeof Tag.float\n | typeof Tag.int32\n | typeof Tag.int64\n | typeof Tag.nil\n | typeof Tag.text\n | typeof Tag.coordinates\n | typeof Tag.map\n | typeof Tag.sorted\n }\n\n /** Match Type from Tag symbol */\n export type TypeFromTag<Kind extends Tag.T> = Kind extends typeof Tag.bool\n ? Bool\n : Kind extends typeof Tag.bytes\n ? Uint8Array\n : Kind extends typeof Tag.timestamp\n ? Timestamp\n : Kind extends typeof Tag.float\n ? Float\n : Kind extends typeof Tag.int32\n ? Int32\n : Kind extends typeof Tag.int64\n ? Int64\n : Kind extends typeof Tag.nil\n ? Null\n : Kind extends typeof Tag.text\n ? Text\n : Kind extends typeof Tag.coordinates\n ? Coordinates\n : Kind extends typeof Tag.map\n ? Map\n : Kind extends typeof Tag.sorted\n ? Sorted<any>\n : never\n}\n\n/** Field */\nexport type FieldValueType<T = any> = FT.Any<T>\n/** Document */\nexport type DocumentType<F extends FieldValueType = any> = {\n [fieldId: string]: F\n}\n/** Collection */\nexport type CollectionType = {[documentId: string]: DocumentType}\n/** Database */\nexport type DatabaseType = {[collectionId: string]: CollectionType}\n/** Cluster */\nexport type ClusterType = {[databaseId: string]: DatabaseType}\n\n/**\n * Outlines schemas for entity types (e.g., field, doc, collection)\n */\nexport namespace Schema {\n /**\n * Name fields\n */\n export type Name = {\n singular?: FT.Text\n plural?: FT.Text\n }\n\n /**\n * Interface properties for a timestamp lifecycle\n *\n * @export\n * @interface StampedLifecycle\n */\n export type StampedLifecycle = Partial<Record<StampedKeys, FT.Timestamp>>\n export type StampedKeys = 'created' | 'updated' | 'delete'\n\n /** Just a boxed name field */\n export interface NamedField {\n name: Name\n }\n\n /**\n * Describes the meta object for a field instance\n */\n export interface FieldDefinition extends NamedField {\n type: FT.Tag.T\n description?: FT.Text\n }\n\n /**\n * Outlines the fields to be designated for a new\n * document instance within the parent collection\n */\n export type ModelFields = {\n [fieldId: string]: FieldDefinition\n }\n\n /**\n * Describes a collection of documents, the fields\n * property describes the fields of any document an\n * instance of the collection.\n */\n export interface CollectionModel\n extends DocumentType,\n StampedLifecycle,\n NamedField {\n fields: ModelFields\n }\n\n /**\n * Describes a collection of documents, each document\n * only describes another collection e.g. the meta\n */\n export type CollectionModels = CollectionType & {\n [collectionIdAsDocumentId: string]: CollectionModel\n }\n\n /**\n * =======================================================\n */\n\n /**\n * The actual collection instance of a collection meta\n */\n export type CollectionInstance<T extends CollectionModel> = CollectionType & {\n [documentId: string]: DocumentType<\n FT.TypeFromTag<T['fields'][string]['type']>\n >\n }\n\n /**\n * Just simply a database of collections\n */\n export type DatabaseCollections<C extends CollectionModels> = DatabaseType & {\n [CID in keyof C]: CollectionInstance<C[CID]>\n }\n}\n\nexport namespace Ref {\n export interface Base<S = any> {\n id: PKey\n schema: S\n }\n\n /**\n * =======================================================\n */\n export type Field<S extends Schema.FieldDefinition> = FT.TypeFromTag<\n S['type']\n >\n\n /**\n * =======================================================\n */\n export type DocumentFields<S extends Schema.ModelFields> = {\n [K in keyof S]: Field<S[K]>\n }\n export type Document<S extends Schema.ModelFields> = DocumentFields<S>\n\n /**\n * =======================================================\n */\n export type CollectionDocuments<S extends Schema.CollectionModel> = {\n [documentId: string]: Document<S['fields']>\n }\n export type Collection<S extends Schema.CollectionModel> =\n CollectionDocuments<S>\n\n /**\n * =======================================================\n */\n // export type DatabaseCollections<S extends Schema.CollectionModels> = {\n // [K in keyof S]: Collection<S[K]>\n // }\n export interface Database {\n schemas: Schema.CollectionModels\n instances: Schema.DatabaseCollections<this['schemas']>\n }\n}\n\n/**\n * Evaluation kinds\n */\nexport enum Eval {\n Required = 'r6d',\n Regex = 'r3x',\n}\n\n/**\n * Property name index signatures\n */\nexport const Sig = {\n Field: 'field',\n Fields: 'fields',\n Document: 'document',\n Documents: 'documents',\n Collection: 'collection',\n Collections: 'collections',\n Subcollection: 'subcollection',\n Subcollections: 'subcollections',\n\n Model: 'model',\n Models: 'models',\n Blueprint: 'blueprint',\n Blueprints: 'blueprints',\n Entry: 'entry',\n Entries: 'entries',\n\n Id: 'id',\n Name: 'name',\n Kind: 'kind',\n Type: 'type',\n Value: 'value',\n\n Created: 'created',\n Updated: 'updated',\n Deleted: 'deleted',\n}\n\n/**\n * Friendly-text/display-names of local names or\n *\n * TODO: i18n\n */\nexport const lbl = {\n /** Field Data Types */\n [FT.Tag.bool]: 'True/False',\n [FT.Tag.bytes]: 'Bytes',\n [FT.Tag.timestamp]: 'Date/Time',\n [FT.Tag.float]: 'Decimal',\n [FT.Tag.int32]: 'Number',\n [FT.Tag.int64]: 'Large Number',\n [FT.Tag.nil]: 'Null',\n [FT.Tag.text]: 'Text',\n [FT.Tag.coordinates]: 'Coordinates (lat/lon)',\n [FT.Tag.map]: 'Map',\n [FT.Tag.sorted]: 'Sorted',\n\n /** Entity type fields */\n [Sig.Field]: 'Field',\n [Sig.Fields]: 'Fields',\n [Sig.Document]: 'Document',\n [Sig.Documents]: 'Documents',\n [Sig.Collection]: 'Collection',\n [Sig.Collections]: 'Collections',\n [Sig.Subcollection]: 'Subcollection',\n [Sig.Subcollections]: 'Subcollections',\n\n /** Instance fields */\n [Sig.Blueprint]: 'Blueprint',\n [Sig.Blueprints]: 'Blueprints',\n [Sig.Model]: 'Model',\n [Sig.Models]: 'Models',\n [Sig.Entry]: 'Entry',\n [Sig.Entries]: 'Entries',\n\n /** Meta fields */\n [Sig.Id]: 'Unique ID',\n [Sig.Name]: 'Display Name',\n [Sig.Kind]: 'Kind',\n [Sig.Type]: 'Type',\n [Sig.Value]: 'Value',\n\n /** Timestamp fields */\n [Sig.Created]: 'Created At',\n [Sig.Updated]: 'Updated At',\n [Sig.Deleted]: 'Deleted At',\n}\n\n/** Contextual persistence types */\nexport enum Persistance {\n NONE = 'NONE',\n SESSION = 'SESSION',\n LOCAL = 'LOCAL',\n}\n"],"names":["FT","Tag","bool","bytes","timestamp","float","int32","int64","nil","text","coordinates","map","sorted","all","Eval","Sig","Field","Fields","Document","Documents","Collection","Collections","Subcollection","Subcollections","Model","Models","Blueprint","Blueprints","Entry","Entries","Id","Name","Kind","Type","Value","Created","Updated","Deleted","lbl","Persistance"],"mappings":"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"}
@@ -0,0 +1,138 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /**
18
+ * Persisted host theme document types.
19
+ *
20
+ * These are plain-JSON (Firestore round-trippable) descriptions of a MUI
21
+ * theme. They intentionally carry no MUI imports so data-scope libs can
22
+ * depend on them; `@aglyn/shared-ui-theme` owns the conversion into runtime
23
+ * `ThemeOptions`.
24
+ */
25
+ export type HostThemeScheme = 'light' | 'dark';
26
+ export interface HostThemePaletteColor {
27
+ main: string;
28
+ light?: string;
29
+ dark?: string;
30
+ contrastText?: string;
31
+ }
32
+ /**
33
+ * Pale washes of the three accents, used as SURFACES (AGL-1244).
34
+ *
35
+ * Deliberately NOT a {@link HostThemePaletteColor}: a tint has no ramp and no
36
+ * `contrastText`, because it is never a component `color`. It is the fill
37
+ * behind an icon that is already `primary.dark` / `secondary.main` /
38
+ * `tertiary.main`, so its members are named after the accent they belong to
39
+ * rather than after a shade. Same shape as `background` and `text` — a group
40
+ * of string leaves — which is why the theme editor reads and writes it
41
+ * through the same path-based fields.
42
+ */
43
+ export interface HostThemeTintColors {
44
+ primary?: string;
45
+ secondary?: string;
46
+ tertiary?: string;
47
+ }
48
+ /** Palette color keys supported per scheme, including repo-custom ones. */
49
+ export interface HostThemeSchemeColors {
50
+ primary?: HostThemePaletteColor;
51
+ secondary?: HostThemePaletteColor;
52
+ tertiary?: HostThemePaletteColor;
53
+ surface?: HostThemePaletteColor;
54
+ error?: HostThemePaletteColor;
55
+ warning?: HostThemePaletteColor;
56
+ info?: HostThemePaletteColor;
57
+ success?: HostThemePaletteColor;
58
+ background?: {
59
+ default?: string;
60
+ paper?: string;
61
+ };
62
+ text?: {
63
+ primary?: string;
64
+ secondary?: string;
65
+ disabled?: string;
66
+ };
67
+ tint?: HostThemeTintColors;
68
+ divider?: string;
69
+ }
70
+ export interface HostThemeFont {
71
+ /** Font family name, e.g. "Inter". */
72
+ family: string;
73
+ weights?: Array<number>;
74
+ /** Where the tenant loads the font from; system fonts need no loading. */
75
+ source?: 'google' | 'system';
76
+ }
77
+ export type HostThemeTypographyVariantKey = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'subtitle1' | 'subtitle2' | 'body1' | 'body2' | 'button' | 'caption' | 'overline';
78
+ export interface HostThemeTypographyVariant {
79
+ fontFamily?: string;
80
+ fontSize?: string | number;
81
+ fontWeight?: number;
82
+ lineHeight?: string | number;
83
+ letterSpacing?: string | number;
84
+ textTransform?: 'none' | 'capitalize' | 'uppercase' | 'lowercase';
85
+ }
86
+ export interface HostThemeTypography {
87
+ /** CSS font-family stack applied theme-wide. */
88
+ fontFamily?: string;
89
+ variants?: {
90
+ [P in HostThemeTypographyVariantKey]?: HostThemeTypographyVariant;
91
+ };
92
+ }
93
+ /**
94
+ * Plain-JSON component override: serialized `defaultProps` and
95
+ * `styleOverrides` (slot name -> CSS object). Functions are not
96
+ * representable by design.
97
+ */
98
+ export interface HostThemeComponentOverride {
99
+ defaultProps?: Record<string, unknown>;
100
+ styleOverrides?: Record<string, unknown>;
101
+ }
102
+ /**
103
+ * Plain-JSON theme mixins.
104
+ *
105
+ * `toolbar` is the only one a host can set, and it exists because it is the
106
+ * ONLY way to change toolbar height from data (AGL-1242). MUI builds the
107
+ * Toolbar's `regular` variant style FROM `theme.mixins.toolbar`, and applies
108
+ * that variant AFTER `components.MuiToolbar.styleOverrides` — so a slot
109
+ * override can never win, no matter how it is written. The value is a CSS
110
+ * object and may nest media queries, e.g.
111
+ * `{ minHeight: '56px', '@media (min-width:600px)': { minHeight: '72px' } }`.
112
+ */
113
+ export interface HostThemeMixins {
114
+ toolbar?: Record<string, unknown>;
115
+ }
116
+ export interface HostTheme {
117
+ colorSchemes?: {
118
+ [P in HostThemeScheme]?: HostThemeSchemeColors;
119
+ };
120
+ typography?: HostThemeTypography;
121
+ fonts?: Array<HostThemeFont>;
122
+ shape?: {
123
+ borderRadius?: number;
124
+ };
125
+ spacing?: number;
126
+ mixins?: HostThemeMixins;
127
+ /** Keyed by MUI component slot name (e.g. `MuiButton`). Consumers validate against a whitelist. */
128
+ components?: Record<string, HostThemeComponentOverride>;
129
+ /**
130
+ * Whether visitors get a dark scheme. Absent (`'auto'`) follows the
131
+ * visitor's system setting or their choice in the theme mode switcher,
132
+ * rendering the platform's default dark palette under whatever dark colors
133
+ * the site authored. `'off'` keeps every visitor on light — for a site whose
134
+ * content carries light-only backgrounds — and hides the switcher on
135
+ * published pages.
136
+ */
137
+ darkScheme?: 'auto' | 'off';
138
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ /**
17
+ * Persisted host theme document types.
18
+ *
19
+ * These are plain-JSON (Firestore round-trippable) descriptions of a MUI
20
+ * theme. They intentionally carry no MUI imports so data-scope libs can
21
+ * depend on them; `@aglyn/shared-ui-theme` owns the conversion into runtime
22
+ * `ThemeOptions`.
23
+ */ export { };
24
+
25
+ //# sourceMappingURL=host-theme.js.map