@mintjamsinc/ichigojs 0.1.81 → 0.1.83

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,118 @@
1
+ import { VBindings } from "./VBindings";
2
+ /**
3
+ * Options for expression evaluation.
4
+ */
5
+ export interface ExpressionEvaluatorOptions {
6
+ /**
7
+ * Additional context variables to be available in the expression (e.g., 'event', '$ctx').
8
+ */
9
+ additionalContext?: Record<string, any>;
10
+ /**
11
+ * If true, allows assignment expressions (e.g., "count++", "value = 10").
12
+ * This is used by VOnDirective to support inline assignments.
13
+ * Default: false
14
+ */
15
+ allowAssignment?: boolean;
16
+ /**
17
+ * A custom function to rewrite the expression before evaluation.
18
+ * This is used by VOnDirective to transform identifiers into 'this.identifier' form.
19
+ */
20
+ rewriteExpression?: (expression: string, identifiers: string[]) => string;
21
+ }
22
+ /**
23
+ * A centralized expression evaluator that normalizes expression evaluation across all directives.
24
+ *
25
+ * This class provides:
26
+ * - Consistent identifier extraction and binding resolution
27
+ * - Unified global object whitelisting (Math, Date, JSON, etc.)
28
+ * - Expression caching for performance
29
+ * - Centralized error handling
30
+ * - Support for custom expression rewriting (for VOnDirective)
31
+ *
32
+ * Example usage:
33
+ * ```typescript
34
+ * const evaluator = ExpressionEvaluator.create(
35
+ * "count + 1",
36
+ * bindings,
37
+ * functionDependencies
38
+ * );
39
+ * const result = evaluator.evaluate();
40
+ * ```
41
+ */
42
+ export declare class ExpressionEvaluator {
43
+ /**
44
+ * Cache for compiled expression functions.
45
+ * Key: expression string
46
+ * Value: compiled function
47
+ */
48
+ private static readonly cache;
49
+ /**
50
+ * Global objects that are whitelisted for use in expressions.
51
+ * These objects are available to all expressions for convenience and compatibility.
52
+ */
53
+ private static readonly GLOBAL_WHITELIST;
54
+ /**
55
+ * The original expression string.
56
+ */
57
+ private readonly expression;
58
+ /**
59
+ * The identifiers extracted from the expression.
60
+ */
61
+ private readonly identifiers;
62
+ /**
63
+ * The bindings to use for evaluating the expression.
64
+ */
65
+ private readonly bindings;
66
+ /**
67
+ * The compiled function for evaluating the expression.
68
+ */
69
+ private readonly evaluatorFunc;
70
+ /**
71
+ * Additional context variables (e.g., 'event', '$ctx').
72
+ */
73
+ private readonly additionalContext?;
74
+ /**
75
+ * Private constructor. Use ExpressionEvaluator.create() to create instances.
76
+ */
77
+ private constructor();
78
+ /**
79
+ * Creates an ExpressionEvaluator instance.
80
+ *
81
+ * @param expression The expression string to evaluate.
82
+ * @param bindings The bindings to use for evaluating the expression.
83
+ * @param functionDependencies A dictionary mapping function names to their dependencies.
84
+ * @param options Optional configuration for the evaluator.
85
+ * @returns An ExpressionEvaluator instance.
86
+ */
87
+ static create(expression: string, bindings: VBindings, functionDependencies: Record<string, string[]>, options?: ExpressionEvaluatorOptions): ExpressionEvaluator;
88
+ /**
89
+ * Compiles an expression into a function.
90
+ *
91
+ * @param expression The expression string to compile.
92
+ * @param identifiers The identifiers extracted from the expression.
93
+ * @param options Optional configuration.
94
+ * @returns A compiled function.
95
+ */
96
+ private static compileExpression;
97
+ /**
98
+ * Evaluates the expression with the current bindings.
99
+ *
100
+ * @returns The result of the expression evaluation.
101
+ */
102
+ evaluate(): any;
103
+ /**
104
+ * Evaluates the expression and returns the result as a boolean.
105
+ *
106
+ * @returns The boolean result of the expression evaluation.
107
+ */
108
+ evaluateAsBoolean(): boolean;
109
+ /**
110
+ * Gets the list of identifiers extracted from the expression.
111
+ */
112
+ get dependentIdentifiers(): string[];
113
+ /**
114
+ * Clears the expression cache.
115
+ * This should be called sparingly, as it will force recompilation of all expressions.
116
+ */
117
+ static clearCache(): void;
118
+ }
@@ -0,0 +1,2 @@
1
+ export declare class VComponent {
2
+ }
@@ -0,0 +1,2 @@
1
+ export declare class VComponentRegistry {
2
+ }
@@ -175,6 +175,7 @@ export declare class VNode {
175
175
  * 4. Unregister dependencies
176
176
  * 5. Clean up directive manager
177
177
  * 6. Call onUnmounted lifecycle hooks
178
+ * 7. Leave the parent's child list
178
179
  */
179
180
  destroy(): void;
180
181
  }
@@ -0,0 +1,21 @@
1
+ import { VBindings } from "./VBindings";
2
+ /**
3
+ * Context provided during the update of the virtual DOM.
4
+ * This context includes the current bindings and a list of identifiers that have changed.
5
+ */
6
+ export interface VUpdateContext {
7
+ /**
8
+ * The current bindings.
9
+ */
10
+ bindings: VBindings;
11
+ /**
12
+ * A list of variable and function names whose values have changed.
13
+ */
14
+ changedIdentifiers: string[];
15
+ /**
16
+ * Indicates if this is the initial update.
17
+ * This flag is true when the update is being performed for the first time after the VNode's creation.
18
+ * It can be used to optimize rendering or initialization logic that should only run once.
19
+ */
20
+ isInitial?: boolean;
21
+ }
@@ -36,9 +36,13 @@ export interface ScopedSlotEntry {
36
36
  * microtask fires, so data() can read them. A component used without any prop
37
37
  * binding still mounts — with its declared defaults — instead of waiting forever.
38
38
  *
39
- * Slot content is captured on the first connection and cached, so a component
40
- * that is moved in the DOM (e.g. reordered by v-for) re-expands its template
41
- * and redistributes the same slot nodes on reconnection.
39
+ * Slot content is captured on the first expansion and cached. The nodes are the
40
+ * parent application's compiled nodes and are only ever moved, never cloned:
41
+ * each `<slot>` outlet the component renders moves them into place
42
+ * (VStaticSlotOutletDirective; scoped `<template v-slot>` content is rendered
43
+ * per outlet by VSlotOutletDirective instead). A component that is moved in
44
+ * the DOM (e.g. reordered by v-for) re-expands its template, and its outlets
45
+ * move the same nodes into the fresh expansion.
42
46
  *
43
47
  * Subclasses must set the static fields _template, _props, _propOptions and
44
48
  * _buildOptions before calling customElements.define(). defineComponent()
@@ -76,6 +80,13 @@ export declare class IchigoElement extends HTMLElement {
76
80
  * VSlotOutletDirective when the component template renders a `<slot>`.
77
81
  */
78
82
  get _ichigoScopedSlots(): Map<string, ScopedSlotEntry> | undefined;
83
+ /**
84
+ * The static slot content captured for the given slot name ('default'
85
+ * for the unnamed slot): the parent application's nodes, moved into place
86
+ * by VStaticSlotOutletDirective. Undefined when nothing was provided for
87
+ * that name, in which case the outlet's fallback content renders.
88
+ */
89
+ _ichigoSlotNodes(name: string): Node[] | undefined;
79
90
  /**
80
91
  * Handles RE-attachment, and nothing else.
81
92
  *
@@ -0,0 +1,24 @@
1
+ import { VBindings } from "../VBindings";
2
+ /**
3
+ * Interface representing a preparer for VBindings in the virtual DOM.
4
+ */
5
+ export interface VBindingsPreparer {
6
+ /**
7
+ * The list of identifiers that this preparer is concerned with.
8
+ * These identifiers are used to determine when the bindings need to be prepared.
9
+ */
10
+ get identifiers(): string[];
11
+ /**
12
+ * The list of identifiers that can be prepared by this preparer.
13
+ * This is a subset of the identifiers property.
14
+ */
15
+ get preparableIdentifiers(): string[];
16
+ /**
17
+ * Prepares the VBindings for the virtual node.
18
+ * This method is called before the bindings are applied to the DOM.
19
+ * It allows for any necessary transformations or initializations of the bindings.
20
+ * @param bindings The original VBindings to be prepared.
21
+ * @returns The prepared VBindings.
22
+ */
23
+ prepareBindings(bindings: VBindings): VBindings;
24
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Interface representing an updater for the virtual DOM.
3
+ * An implementation of this interface is responsible for applying changes
4
+ * from the virtual DOM to the actual DOM.
5
+ */
6
+ export interface VDOMUpdater {
7
+ /**
8
+ * A list of variable and function names that this updater is concerned with.
9
+ * Changes to these identifiers may trigger the updater to apply changes to the DOM.
10
+ */
11
+ get identifiers(): string[];
12
+ /**
13
+ * Applies the changes from the virtual DOM to the actual DOM.
14
+ * This method is called when the identifiers change or when an update is needed.
15
+ */
16
+ applyToDOM(): void;
17
+ }
@@ -26,9 +26,9 @@ import { VDOMUpdater } from "../VDOMUpdater";
26
26
  * ```
27
27
  *
28
28
  * This directive is created only when a scoped template for the slot's name
29
- * exists (see {@link VSlotOutletDirective.tryCreate}); otherwise `<slot>`
30
- * elements keep their existing behavior (static distribution at expansion,
31
- * or fallback content compiled in the component scope).
29
+ * exists (see {@link VSlotOutletDirective.tryCreate}); otherwise plain slot
30
+ * content is moved into place by VStaticSlotOutletDirective, and a `<slot>`
31
+ * with no content at all renders its fallback in the component scope.
32
32
  *
33
33
  * Rendering happens synchronously in onMount — before the component
34
34
  * application would compile the slot's fallback children — by replacing the
@@ -0,0 +1,129 @@
1
+ import type { VNode } from "../VNode";
2
+ import { VBindingsPreparer } from "../VBindingsPreparer";
3
+ import { VDirective } from "./VDirective";
4
+ import { VDOMUpdater } from "../VDOMUpdater";
5
+ /**
6
+ * Renders a static slot outlet: a `<slot>` element inside a component template
7
+ * whose host element received plain slot content from the parent — child
8
+ * nodes for the default slot, or elements carrying `slot="name"`:
9
+ *
10
+ * ```html
11
+ * <!-- component template -->
12
+ * <div v-if="open" class="body"><slot></slot></div>
13
+ *
14
+ * <!-- usage -->
15
+ * <my-dialog :open="show">
16
+ * <my-field :label="title"></my-field>
17
+ * </my-dialog>
18
+ * ```
19
+ *
20
+ * The slot content is the parent application's own nodes, compiled in the
21
+ * parent scope; it keeps its bindings, listeners and component props only as
22
+ * long as those very nodes are displayed. So the outlet MOVES them into place
23
+ * and never clones them. That is what lets a `<slot>` sit behind a v-if or
24
+ * v-for in the component template: the directive clones its template source,
25
+ * the clone carries a fresh `<slot>`, and the outlet created for that clone
26
+ * moves the live nodes in.
27
+ *
28
+ * Nodes can only be in one place, so when the same slot is rendered more than
29
+ * once (e.g. a `<slot>` inside a v-for), the outlet rendered last receives the
30
+ * content and the earlier ones are left empty. When the outlet holding the
31
+ * content goes away while others remain (its row is removed), the content
32
+ * moves to the last remaining one. For content per row, use a scoped slot
33
+ * (`<template v-slot:name="scope">`), which renders a copy per outlet
34
+ * (VSlotOutletDirective).
35
+ *
36
+ * The component application never compiles the moved nodes: they are placed
37
+ * in onMount, after the parent VNode has taken its snapshot of the children
38
+ * to compile. Components inside them belong to the parent application, which
39
+ * expands them through {@link expandComponents} once they are in the document.
40
+ * When the last outlet goes away (its v-if turns false) the nodes leave with
41
+ * the removed clone and wait there until the next outlet moves them again;
42
+ * they are not destroyed, because they are not this application's to destroy.
43
+ *
44
+ * Created only when the host captured content for the slot's name and no
45
+ * scoped template claims it; otherwise the `<slot>` element renders its
46
+ * fallback children in the component scope.
47
+ */
48
+ export declare class VStaticSlotOutletDirective implements VDirective {
49
+ #private;
50
+ /**
51
+ * Creates a static slot outlet for the given `<slot>` VNode when the host
52
+ * element captured content for its slot name. Returns undefined when there
53
+ * is none, so the `<slot>` element keeps rendering its fallback content.
54
+ */
55
+ static tryCreate(vNode: VNode): VStaticSlotOutletDirective | undefined;
56
+ private constructor();
57
+ /**
58
+ * @inheritdoc
59
+ */
60
+ get name(): string;
61
+ /**
62
+ * @inheritdoc
63
+ */
64
+ get vNode(): VNode;
65
+ /**
66
+ * @inheritdoc
67
+ */
68
+ get needsAnchor(): boolean;
69
+ /**
70
+ * @inheritdoc
71
+ */
72
+ get bindingsPreparer(): VBindingsPreparer | undefined;
73
+ /**
74
+ * @inheritdoc
75
+ */
76
+ get domUpdater(): VDOMUpdater | undefined;
77
+ /**
78
+ * @inheritdoc
79
+ */
80
+ get templatize(): boolean;
81
+ /**
82
+ * @inheritdoc
83
+ */
84
+ get dependentIdentifiers(): string[];
85
+ /**
86
+ * @inheritdoc
87
+ *
88
+ * Moves the slot content in place of the `<slot>` element — synchronously
89
+ * during VNode construction, before the component application would
90
+ * compile the slot's fallback children (which the content replaces).
91
+ */
92
+ get onMount(): (() => void) | undefined;
93
+ /**
94
+ * @inheritdoc
95
+ */
96
+ get onMounted(): (() => void) | undefined;
97
+ /**
98
+ * @inheritdoc
99
+ */
100
+ get onUpdate(): (() => void) | undefined;
101
+ /**
102
+ * @inheritdoc
103
+ */
104
+ get onUpdated(): (() => void) | undefined;
105
+ /**
106
+ * @inheritdoc
107
+ */
108
+ get onUnmount(): (() => void) | undefined;
109
+ /**
110
+ * @inheritdoc
111
+ */
112
+ get onUnmounted(): (() => void) | undefined;
113
+ /**
114
+ * @inheritdoc
115
+ *
116
+ * Expands the components in the slot content through the parent
117
+ * application's VNodes. Called by the walk of whoever inserted this
118
+ * outlet into the document (VApplication.mount, v-if, v-for), so the
119
+ * content is connected by now — unless a later outlet took it, in which
120
+ * case that outlet's walk expands it.
121
+ */
122
+ expandComponents(): void;
123
+ /**
124
+ * @inheritdoc
125
+ *
126
+ * The slot content is the parent application's; nothing to release here.
127
+ */
128
+ destroy(): void;
129
+ }
@@ -0,0 +1,10 @@
1
+ import { VBindings } from "../VBindings";
2
+ export declare class BindingsUtils {
3
+ /**
4
+ * Gets the identifiers that have changed between two sets of bindings.
5
+ * @param oldBindings The old set of bindings.
6
+ * @param newBindings The new set of bindings.
7
+ * @returns An array of identifiers that have changed.
8
+ */
9
+ static getChangedIdentifiers(oldBindings: VBindings, newBindings: VBindings): string[];
10
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Log level enumeration.
3
+ */
4
+ export declare enum VLogLevel {
5
+ DEBUG = "debug",
6
+ INFO = "info",
7
+ WARN = "warn",
8
+ ERROR = "error"
9
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mintjamsinc/ichigojs",
3
- "version": "0.1.81",
3
+ "version": "0.1.83",
4
4
  "description": "ichigo.js - Simple and intuitive reactive framework. Lightweight, fast, and user-friendly virtual DOM library",
5
5
  "main": "./dist/ichigo.cjs",
6
6
  "module": "./dist/ichigo.esm.js",