@mintjamsinc/ichigojs 0.1.10 → 0.1.12
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.
- package/dist/ichigo.esm.js +365 -12
- package/dist/ichigo.esm.js.map +1 -1
- package/dist/ichigo.esm.min.js +1 -1
- package/dist/ichigo.esm.min.js.map +1 -1
- package/dist/ichigo.umd.js +366 -11
- package/dist/ichigo.umd.js.map +1 -1
- package/dist/ichigo.umd.min.js +1 -1
- package/dist/ichigo.umd.min.js.map +1 -1
- package/dist/types/ichigo/VApplication.d.ts +8 -2
- package/dist/types/ichigo/components/VComponent.d.ts +23 -0
- package/dist/types/ichigo/components/VComponentRegistry.d.ts +35 -0
- package/dist/types/ichigo/directives/StandardDirectiveName.d.ts +3 -1
- package/dist/types/ichigo/directives/VComponentDirective.d.ts +81 -0
- package/dist/types/index.d.ts +2 -0
- package/package.json +1 -1
package/dist/ichigo.umd.js
CHANGED
@@ -5,7 +5,96 @@
|
|
5
5
|
})(this, (function (exports) { 'use strict';
|
6
6
|
|
7
7
|
// Copyright (c) 2025 MintJams Inc. Licensed under MIT License.
|
8
|
+
/**
|
9
|
+
* Represents a reusable component definition.
|
10
|
+
*/
|
11
|
+
class VComponent {
|
12
|
+
/**
|
13
|
+
* The unique identifier for the component.
|
14
|
+
*/
|
15
|
+
id;
|
16
|
+
/**
|
17
|
+
* The function that creates a new instance of the component.
|
18
|
+
*/
|
19
|
+
createInstance;
|
20
|
+
/**
|
21
|
+
* The optional template ID for the component.
|
22
|
+
* If not specified, defaults to the component ID.
|
23
|
+
*/
|
24
|
+
templateID;
|
25
|
+
/**
|
26
|
+
* Creates a new component definition.
|
27
|
+
* @param id The unique identifier for the component.
|
28
|
+
* @param createInstance The function that creates a new instance of the component.
|
29
|
+
* @param templateID The optional template ID for the component.
|
30
|
+
*/
|
31
|
+
constructor(id, createInstance, templateID) {
|
32
|
+
if (!id || typeof id !== 'string') {
|
33
|
+
throw new Error('Component ID must be a non-empty string.');
|
34
|
+
}
|
35
|
+
if (typeof createInstance !== 'function') {
|
36
|
+
throw new Error('createInstance must be a function.');
|
37
|
+
}
|
38
|
+
this.id = id.trim();
|
39
|
+
this.createInstance = createInstance;
|
40
|
+
this.templateID = templateID?.trim() || this.id;
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
// Copyright (c) 2025 MintJams Inc. Licensed under MIT License.
|
45
|
+
/**
|
46
|
+
* A registry for managing component definitions.
|
47
|
+
*/
|
8
48
|
class VComponentRegistry {
|
49
|
+
/**
|
50
|
+
* Map of component ID to component definition.
|
51
|
+
*/
|
52
|
+
#components = new Map();
|
53
|
+
/**
|
54
|
+
* Registers a new component.
|
55
|
+
* @param id The unique identifier for the component.
|
56
|
+
* @param createInstance The function that creates a new instance of the component.
|
57
|
+
* @param templateID The optional template ID for the component.
|
58
|
+
* @returns True if the component was registered, false if a component with the same ID already exists.
|
59
|
+
*/
|
60
|
+
register(id, createInstance, templateID) {
|
61
|
+
if (this.has(id)) {
|
62
|
+
return false;
|
63
|
+
}
|
64
|
+
const component = new VComponent(id, createInstance, templateID);
|
65
|
+
this.#components.set(id, component);
|
66
|
+
return true;
|
67
|
+
}
|
68
|
+
/**
|
69
|
+
* Checks if a component with the given ID exists.
|
70
|
+
* @param id The component ID to check.
|
71
|
+
* @returns True if the component exists, false otherwise.
|
72
|
+
*/
|
73
|
+
has(id) {
|
74
|
+
return this.#components.has(id);
|
75
|
+
}
|
76
|
+
/**
|
77
|
+
* Gets a component by its ID.
|
78
|
+
* @param id The component ID to retrieve.
|
79
|
+
* @returns The component definition, or undefined if not found.
|
80
|
+
*/
|
81
|
+
get(id) {
|
82
|
+
return this.#components.get(id);
|
83
|
+
}
|
84
|
+
/**
|
85
|
+
* Removes a component from the registry.
|
86
|
+
* @param id The component ID to remove.
|
87
|
+
* @returns True if the component was removed, false if it didn't exist.
|
88
|
+
*/
|
89
|
+
unregister(id) {
|
90
|
+
return this.#components.delete(id);
|
91
|
+
}
|
92
|
+
/**
|
93
|
+
* Clears all registered components.
|
94
|
+
*/
|
95
|
+
clear() {
|
96
|
+
this.#components.clear();
|
97
|
+
}
|
9
98
|
}
|
10
99
|
|
11
100
|
// Copyright (c) 2025 MintJams Inc. Licensed under MIT License.
|
@@ -80,6 +169,8 @@
|
|
80
169
|
StandardDirectiveName["V_INTERSECTION"] = "v-intersection";
|
81
170
|
/** Performance observer directives. */
|
82
171
|
StandardDirectiveName["V_PERFORMANCE"] = "v-performance";
|
172
|
+
/** Component directive. */
|
173
|
+
StandardDirectiveName["V_COMPONENT"] = "v-component";
|
83
174
|
})(StandardDirectiveName || (StandardDirectiveName = {}));
|
84
175
|
|
85
176
|
// This file was generated. Do not modify manually!
|
@@ -6646,10 +6737,16 @@
|
|
6646
6737
|
const isArrowFunction = /^\s*(\([^)]*\)|[a-zA-Z_$][a-zA-Z0-9_$]*)\s*=>/.test(source);
|
6647
6738
|
const isFunctionExpression = source.startsWith('function');
|
6648
6739
|
const isAsyncFunction = source.startsWith('async');
|
6649
|
-
// If it's a method shorthand (e.g., "methodName() { ... }"), convert to function expression
|
6650
|
-
if (!isFunctionExpression && !isArrowFunction
|
6740
|
+
// If it's a method shorthand (e.g., "methodName() { ... }" or "async methodName() { ... }"), convert to function expression
|
6741
|
+
if (!isFunctionExpression && !isArrowFunction) {
|
6651
6742
|
// It's likely a method shorthand, convert to function expression
|
6652
|
-
|
6743
|
+
if (isAsyncFunction) {
|
6744
|
+
// Remove 'async' prefix and add 'async function' prefix
|
6745
|
+
source = `async function ${source.substring(5).trim()}`;
|
6746
|
+
}
|
6747
|
+
else {
|
6748
|
+
source = `function ${source}`;
|
6749
|
+
}
|
6653
6750
|
}
|
6654
6751
|
// Wrap in parentheses for parsing
|
6655
6752
|
source = `(${source})`;
|
@@ -7117,6 +7214,236 @@
|
|
7117
7214
|
}
|
7118
7215
|
}
|
7119
7216
|
|
7217
|
+
// Copyright (c) 2025 MintJams Inc. Licensed under MIT License.
|
7218
|
+
/**
|
7219
|
+
* Directive for rendering components.
|
7220
|
+
* Usage: <div v-component="componentId" :options="props"></div>
|
7221
|
+
*
|
7222
|
+
* The :options binding is used to pass properties to the component.
|
7223
|
+
* Example:
|
7224
|
+
* <div v-component="my-component" :options="{message: 'Hello'}"></div>
|
7225
|
+
*/
|
7226
|
+
class VComponentDirective {
|
7227
|
+
/**
|
7228
|
+
* The virtual node to which this directive is applied.
|
7229
|
+
*/
|
7230
|
+
#vNode;
|
7231
|
+
/**
|
7232
|
+
* The component ID expression.
|
7233
|
+
*/
|
7234
|
+
#expression;
|
7235
|
+
/**
|
7236
|
+
* Whether the component ID is static (not reactive).
|
7237
|
+
*/
|
7238
|
+
#isStatic = false;
|
7239
|
+
/**
|
7240
|
+
* The component ID to render.
|
7241
|
+
*/
|
7242
|
+
#componentId;
|
7243
|
+
/**
|
7244
|
+
* The child application instance for the component.
|
7245
|
+
*/
|
7246
|
+
#childApp;
|
7247
|
+
/**
|
7248
|
+
* Whether the component has been activated.
|
7249
|
+
*/
|
7250
|
+
#isActivated = false;
|
7251
|
+
constructor(context) {
|
7252
|
+
this.#vNode = context.vNode;
|
7253
|
+
this.#expression = context.attribute.value;
|
7254
|
+
// Check for .static modifier
|
7255
|
+
const attrName = context.attribute.name;
|
7256
|
+
this.#isStatic = attrName.includes('.static');
|
7257
|
+
// Remove the directive attribute from the element
|
7258
|
+
this.#vNode.node.removeAttribute(context.attribute.name);
|
7259
|
+
}
|
7260
|
+
/**
|
7261
|
+
* @inheritdoc
|
7262
|
+
*/
|
7263
|
+
get name() {
|
7264
|
+
return StandardDirectiveName.V_COMPONENT;
|
7265
|
+
}
|
7266
|
+
/**
|
7267
|
+
* @inheritdoc
|
7268
|
+
*/
|
7269
|
+
get vNode() {
|
7270
|
+
return this.#vNode;
|
7271
|
+
}
|
7272
|
+
/**
|
7273
|
+
* @inheritdoc
|
7274
|
+
*/
|
7275
|
+
get needsAnchor() {
|
7276
|
+
return false;
|
7277
|
+
}
|
7278
|
+
/**
|
7279
|
+
* @inheritdoc
|
7280
|
+
*/
|
7281
|
+
get bindingsPreparer() {
|
7282
|
+
return undefined;
|
7283
|
+
}
|
7284
|
+
/**
|
7285
|
+
* @inheritdoc
|
7286
|
+
*/
|
7287
|
+
get domUpdater() {
|
7288
|
+
// Create and return the DOM updater
|
7289
|
+
const updater = {
|
7290
|
+
get dependentIdentifiers() {
|
7291
|
+
return [];
|
7292
|
+
},
|
7293
|
+
applyToDOM: () => {
|
7294
|
+
if (!this.#isActivated) {
|
7295
|
+
this.renderComponent();
|
7296
|
+
}
|
7297
|
+
}
|
7298
|
+
};
|
7299
|
+
return updater;
|
7300
|
+
}
|
7301
|
+
/**
|
7302
|
+
* @inheritdoc
|
7303
|
+
*/
|
7304
|
+
get templatize() {
|
7305
|
+
return false;
|
7306
|
+
}
|
7307
|
+
/**
|
7308
|
+
* @inheritdoc
|
7309
|
+
*/
|
7310
|
+
get dependentIdentifiers() {
|
7311
|
+
return [];
|
7312
|
+
}
|
7313
|
+
/**
|
7314
|
+
* @inheritdoc
|
7315
|
+
*/
|
7316
|
+
get onMount() {
|
7317
|
+
return undefined;
|
7318
|
+
}
|
7319
|
+
/**
|
7320
|
+
* @inheritdoc
|
7321
|
+
*/
|
7322
|
+
get onMounted() {
|
7323
|
+
return undefined;
|
7324
|
+
}
|
7325
|
+
/**
|
7326
|
+
* @inheritdoc
|
7327
|
+
*/
|
7328
|
+
get onUpdate() {
|
7329
|
+
return undefined;
|
7330
|
+
}
|
7331
|
+
/**
|
7332
|
+
* @inheritdoc
|
7333
|
+
*/
|
7334
|
+
get onUpdated() {
|
7335
|
+
return undefined;
|
7336
|
+
}
|
7337
|
+
/**
|
7338
|
+
* @inheritdoc
|
7339
|
+
*/
|
7340
|
+
get onUnmount() {
|
7341
|
+
return () => this.cleanupComponent();
|
7342
|
+
}
|
7343
|
+
/**
|
7344
|
+
* @inheritdoc
|
7345
|
+
*/
|
7346
|
+
get onUnmounted() {
|
7347
|
+
return undefined;
|
7348
|
+
}
|
7349
|
+
/**
|
7350
|
+
* @inheritdoc
|
7351
|
+
*/
|
7352
|
+
destroy() {
|
7353
|
+
this.cleanupComponent();
|
7354
|
+
}
|
7355
|
+
/**
|
7356
|
+
* Renders the component.
|
7357
|
+
*/
|
7358
|
+
renderComponent() {
|
7359
|
+
const element = this.#vNode.node;
|
7360
|
+
if (!element) {
|
7361
|
+
return;
|
7362
|
+
}
|
7363
|
+
// For now, only support static component IDs
|
7364
|
+
const componentId = this.#expression.trim();
|
7365
|
+
if (!componentId) {
|
7366
|
+
console.warn(`Component ID is empty for v-component directive`);
|
7367
|
+
return;
|
7368
|
+
}
|
7369
|
+
// Get properties from :options or :options.component directive
|
7370
|
+
let properties = {};
|
7371
|
+
const optionsDirective = this.#vNode.directiveManager?.optionsDirective('component');
|
7372
|
+
if (optionsDirective && optionsDirective.expression) {
|
7373
|
+
// Evaluate the options expression
|
7374
|
+
const identifiers = optionsDirective.dependentIdentifiers;
|
7375
|
+
const values = identifiers.map(id => this.#vNode.bindings?.get(id));
|
7376
|
+
const args = identifiers.join(", ");
|
7377
|
+
const funcBody = `return (${optionsDirective.expression});`;
|
7378
|
+
const func = new Function(args, funcBody);
|
7379
|
+
const result = func(...values);
|
7380
|
+
if (typeof result === 'object' && result !== null) {
|
7381
|
+
properties = result;
|
7382
|
+
}
|
7383
|
+
}
|
7384
|
+
// Store component ID
|
7385
|
+
this.#componentId = componentId;
|
7386
|
+
// Get component definition from the application's component registry
|
7387
|
+
const vApplication = this.#vNode.vApplication;
|
7388
|
+
if (!vApplication) {
|
7389
|
+
console.error('VApplication not found on VNode');
|
7390
|
+
return;
|
7391
|
+
}
|
7392
|
+
const component = vApplication.componentRegistry.get(componentId);
|
7393
|
+
if (!component) {
|
7394
|
+
console.error(`Component '${componentId}' not found in registry`);
|
7395
|
+
return;
|
7396
|
+
}
|
7397
|
+
// Get template element
|
7398
|
+
const finalTemplateID = component.templateID;
|
7399
|
+
const templateElement = document.querySelector(`#${finalTemplateID}`);
|
7400
|
+
if (!templateElement || !(templateElement instanceof HTMLTemplateElement)) {
|
7401
|
+
console.error(`Template element '#${finalTemplateID}' not found`);
|
7402
|
+
return;
|
7403
|
+
}
|
7404
|
+
// Clone template content
|
7405
|
+
const fragment = templateElement.content.cloneNode(true);
|
7406
|
+
const childNodes = Array.from(fragment.childNodes);
|
7407
|
+
// Find the first element node
|
7408
|
+
let componentElement;
|
7409
|
+
for (const node of childNodes) {
|
7410
|
+
if (node.nodeType === Node.ELEMENT_NODE) {
|
7411
|
+
componentElement = node;
|
7412
|
+
break;
|
7413
|
+
}
|
7414
|
+
}
|
7415
|
+
if (!componentElement) {
|
7416
|
+
console.error(`No element found in template '#${finalTemplateID}'`);
|
7417
|
+
return;
|
7418
|
+
}
|
7419
|
+
// Replace element with component element
|
7420
|
+
const parent = element.parentNode;
|
7421
|
+
if (!parent) {
|
7422
|
+
console.error(`Element has no parent node. Component '${componentId}' cannot be mounted.`);
|
7423
|
+
return;
|
7424
|
+
}
|
7425
|
+
parent.insertBefore(componentElement, element);
|
7426
|
+
parent.removeChild(element);
|
7427
|
+
// Create component instance
|
7428
|
+
const instance = component.createInstance(properties);
|
7429
|
+
// Create and mount child application using the parent application's registries
|
7430
|
+
this.#childApp = vApplication.createChildApp(instance);
|
7431
|
+
this.#childApp.mount(componentElement);
|
7432
|
+
this.#isActivated = true;
|
7433
|
+
}
|
7434
|
+
/**
|
7435
|
+
* Cleans up the component.
|
7436
|
+
*/
|
7437
|
+
cleanupComponent() {
|
7438
|
+
if (this.#childApp) {
|
7439
|
+
// TODO: Implement unmount when available in VApplication
|
7440
|
+
// this.#childApp.unmount();
|
7441
|
+
this.#childApp = undefined;
|
7442
|
+
}
|
7443
|
+
this.#isActivated = false;
|
7444
|
+
}
|
7445
|
+
}
|
7446
|
+
|
7120
7447
|
// Copyright (c) 2025 MintJams Inc. Licensed under MIT License.
|
7121
7448
|
/**
|
7122
7449
|
* Utility class for creating reactive proxies that automatically track changes.
|
@@ -7595,7 +7922,11 @@
|
|
7595
7922
|
}
|
7596
7923
|
// If this is an options binding directive, cache it
|
7597
7924
|
if (directive.name === StandardDirectiveName.V_BIND && directive.isOptions) {
|
7598
|
-
|
7925
|
+
const bindDirective = directive;
|
7926
|
+
const attrName = bindDirective.attributeName;
|
7927
|
+
if (attrName) {
|
7928
|
+
this.#optionsDirectives[attrName] = bindDirective;
|
7929
|
+
}
|
7599
7930
|
}
|
7600
7931
|
}
|
7601
7932
|
}
|
@@ -10575,7 +10906,10 @@
|
|
10575
10906
|
// v-intersection
|
10576
10907
|
context.attribute.name === StandardDirectiveName.V_INTERSECTION ||
|
10577
10908
|
// v-performance
|
10578
|
-
context.attribute.name === StandardDirectiveName.V_PERFORMANCE
|
10909
|
+
context.attribute.name === StandardDirectiveName.V_PERFORMANCE ||
|
10910
|
+
// v-component, v-component.<modifier>
|
10911
|
+
context.attribute.name === StandardDirectiveName.V_COMPONENT ||
|
10912
|
+
context.attribute.name.startsWith(StandardDirectiveName.V_COMPONENT + ".")) {
|
10579
10913
|
return true;
|
10580
10914
|
}
|
10581
10915
|
return false;
|
@@ -10626,6 +10960,11 @@
|
|
10626
10960
|
if (context.attribute.name === StandardDirectiveName.V_PERFORMANCE) {
|
10627
10961
|
return new VPerformanceDirective(context);
|
10628
10962
|
}
|
10963
|
+
// v-component, v-component.<modifier>
|
10964
|
+
if (context.attribute.name === StandardDirectiveName.V_COMPONENT ||
|
10965
|
+
context.attribute.name.startsWith(StandardDirectiveName.V_COMPONENT + ".")) {
|
10966
|
+
return new VComponentDirective(context);
|
10967
|
+
}
|
10629
10968
|
throw new Error(`The attribute "${context.attribute.name}" cannot be parsed by ${this.name}.`);
|
10630
10969
|
}
|
10631
10970
|
}
|
@@ -10859,12 +11198,18 @@
|
|
10859
11198
|
}
|
10860
11199
|
/**
|
10861
11200
|
* Mounts the application.
|
10862
|
-
* @param
|
10863
|
-
*/
|
10864
|
-
mount(
|
10865
|
-
|
10866
|
-
if (
|
10867
|
-
|
11201
|
+
* @param target The CSS selector string or HTMLElement to mount the application to.
|
11202
|
+
*/
|
11203
|
+
mount(target) {
|
11204
|
+
let element;
|
11205
|
+
if (typeof target === 'string') {
|
11206
|
+
element = document.querySelector(target);
|
11207
|
+
if (!element) {
|
11208
|
+
throw new Error(`Element not found for selector: ${target}`);
|
11209
|
+
}
|
11210
|
+
}
|
11211
|
+
else {
|
11212
|
+
element = target;
|
10868
11213
|
}
|
10869
11214
|
// Clean the element by removing unnecessary whitespace text nodes
|
10870
11215
|
this.#cleanElement(element);
|
@@ -10878,6 +11223,14 @@
|
|
10878
11223
|
this.#vNode.update();
|
10879
11224
|
this.#logger.info('Application mounted.');
|
10880
11225
|
}
|
11226
|
+
/**
|
11227
|
+
* Creates a child application instance with the same registries.
|
11228
|
+
* @param options The application options for the child.
|
11229
|
+
* @returns The created child application instance.
|
11230
|
+
*/
|
11231
|
+
createChildApp(options) {
|
11232
|
+
return new VApplication(options, this.#directiveParserRegistry, this.#componentRegistry);
|
11233
|
+
}
|
10881
11234
|
/**
|
10882
11235
|
* Cleans the element by removing unnecessary whitespace text nodes.
|
10883
11236
|
* @param element The element to clean.
|
@@ -11114,6 +11467,8 @@
|
|
11114
11467
|
}
|
11115
11468
|
}
|
11116
11469
|
|
11470
|
+
exports.VComponent = VComponent;
|
11471
|
+
exports.VComponentRegistry = VComponentRegistry;
|
11117
11472
|
exports.VDOM = VDOM;
|
11118
11473
|
|
11119
11474
|
}));
|