@mintjamsinc/ichigojs 0.1.9 → 0.1.10
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/README.md +52 -1
- package/dist/ichigo.esm.js +224 -2
- 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 +224 -2
- 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/directives/StandardDirectiveName.d.ts +4 -2
- package/dist/types/ichigo/directives/VPerformanceDirective.d.ts +18 -28
- package/package.json +1 -1
package/README.md
CHANGED
@@ -16,9 +16,10 @@ A simple and intuitive reactive framework. Lightweight, fast, and user-friendly
|
|
16
16
|
- 📦 **Lightweight** - Minimal bundle size
|
17
17
|
- 🚀 **High Performance** - Efficient batched updates via microtask queue
|
18
18
|
- 💪 **TypeScript** - Written in TypeScript with full type support
|
19
|
-
- 🎨 **Directives** - `v-if`, `v-for`, `v-show`, `v-bind`, `v-on`, `v-model`, `v-resize`, `v-intersection`
|
19
|
+
- 🎨 **Directives** - `v-if`, `v-for`, `v-show`, `v-bind`, `v-on`, `v-model`, `v-resize`, `v-intersection`, `v-performance`
|
20
20
|
- 📐 **Resize Observer** - Monitor element size changes with `v-resize` directive
|
21
21
|
- 👁️ **Intersection Observer** - Detect element visibility with `v-intersection` directive
|
22
|
+
- ⚡ **Performance Observer** - Monitor performance metrics with `v-performance` directive
|
22
23
|
|
23
24
|
## Installation
|
24
25
|
|
@@ -272,6 +273,56 @@ You can also use `:options` for generic options:
|
|
272
273
|
- Perfect for lazy loading, infinite scroll, and animation triggers
|
273
274
|
- Access to element, VNode, and userData via `$ctx`
|
274
275
|
|
276
|
+
#### v-performance
|
277
|
+
|
278
|
+
Monitor performance metrics using PerformanceObserver:
|
279
|
+
|
280
|
+
```html
|
281
|
+
<div v-performance="onPerformance">
|
282
|
+
Performance monitoring
|
283
|
+
</div>
|
284
|
+
```
|
285
|
+
|
286
|
+
```javascript
|
287
|
+
methods: {
|
288
|
+
onPerformance(entries, observer, options, $ctx) {
|
289
|
+
entries.getEntries().forEach(entry => {
|
290
|
+
console.log(`${entry.name}: ${entry.duration}ms`);
|
291
|
+
});
|
292
|
+
|
293
|
+
// Access dropped entries count if available
|
294
|
+
if (options?.droppedEntriesCount) {
|
295
|
+
console.log(`Dropped: ${options.droppedEntriesCount}`);
|
296
|
+
}
|
297
|
+
}
|
298
|
+
}
|
299
|
+
```
|
300
|
+
|
301
|
+
**With custom options:**
|
302
|
+
|
303
|
+
```html
|
304
|
+
<div v-performance="onPerformance"
|
305
|
+
:options.performance="{entryTypes: ['measure', 'mark']}">
|
306
|
+
Observe only measures and marks
|
307
|
+
</div>
|
308
|
+
```
|
309
|
+
|
310
|
+
You can also use `:options` for generic options:
|
311
|
+
|
312
|
+
```html
|
313
|
+
<div v-performance="onPerformance"
|
314
|
+
:options="{type: 'navigation', buffered: true}">
|
315
|
+
Performance monitoring
|
316
|
+
</div>
|
317
|
+
```
|
318
|
+
|
319
|
+
**Features:**
|
320
|
+
- Native PerformanceObserver API for monitoring performance metrics
|
321
|
+
- Custom entry types and options via `:options.performance` or `:options`
|
322
|
+
- Automatic cleanup in destroy phase
|
323
|
+
- Monitor marks, measures, navigation, resource timing, and more
|
324
|
+
- Access to element, VNode, and userData via `$ctx`
|
325
|
+
|
275
326
|
#### Lifecycle Hooks
|
276
327
|
|
277
328
|
Lifecycle hooks allow you to run code at specific stages of an element's lifecycle. Each hook receives a **lifecycle context** (`$ctx`) with access to the element, VNode, and userData storage.
|
package/dist/ichigo.esm.js
CHANGED
@@ -68,10 +68,12 @@ var StandardDirectiveName;
|
|
68
68
|
StandardDirectiveName["V_BIND"] = "v-bind";
|
69
69
|
/** Two-way data binding directives. */
|
70
70
|
StandardDirectiveName["V_MODEL"] = "v-model";
|
71
|
-
/**
|
71
|
+
/** Resize observer directives. */
|
72
72
|
StandardDirectiveName["V_RESIZE"] = "v-resize";
|
73
73
|
/** Intersection observer directives. */
|
74
74
|
StandardDirectiveName["V_INTERSECTION"] = "v-intersection";
|
75
|
+
/** Performance observer directives. */
|
76
|
+
StandardDirectiveName["V_PERFORMANCE"] = "v-performance";
|
75
77
|
})(StandardDirectiveName || (StandardDirectiveName = {}));
|
76
78
|
|
77
79
|
// This file was generated. Do not modify manually!
|
@@ -9921,6 +9923,220 @@ class VOnDirective {
|
|
9921
9923
|
}
|
9922
9924
|
}
|
9923
9925
|
|
9926
|
+
// Copyright (c) 2025 MintJams Inc. Licensed under MIT License.
|
9927
|
+
/**
|
9928
|
+
* Directive for observing performance metrics using PerformanceObserver.
|
9929
|
+
* The `v-performance` directive allows you to monitor various performance entries.
|
9930
|
+
*
|
9931
|
+
* Example usage:
|
9932
|
+
* <div v-performance="handlePerformance">Performance monitoring</div>
|
9933
|
+
* <div v-performance="handlePerformance" :options.performance="{entryTypes: ['measure']}">Performance monitoring</div>
|
9934
|
+
*
|
9935
|
+
* By default (without options), it observes 'mark' and 'measure' entry types.
|
9936
|
+
*
|
9937
|
+
* The handler receives PerformanceObserverEntryList, PerformanceObserver, options (with droppedEntriesCount), and $ctx as arguments:
|
9938
|
+
* handlePerformance(entries, observer, options, $ctx) {
|
9939
|
+
* entries.getEntries().forEach(entry => {
|
9940
|
+
* console.log(`${entry.name}: ${entry.duration}ms`);
|
9941
|
+
* });
|
9942
|
+
* if (options?.droppedEntriesCount) {
|
9943
|
+
* console.log(`Dropped entries: ${options.droppedEntriesCount}`);
|
9944
|
+
* }
|
9945
|
+
* }
|
9946
|
+
*
|
9947
|
+
* Options can be provided via :options or :options.performance attribute:
|
9948
|
+
* :options="{entryTypes: ['measure', 'mark']}"
|
9949
|
+
* :options.performance="{type: 'navigation', buffered: true}"
|
9950
|
+
*
|
9951
|
+
* This directive is useful for performance monitoring, profiling, and identifying
|
9952
|
+
* performance bottlenecks in your application.
|
9953
|
+
*/
|
9954
|
+
class VPerformanceDirective {
|
9955
|
+
/**
|
9956
|
+
* The virtual node to which this directive is applied.
|
9957
|
+
*/
|
9958
|
+
#vNode;
|
9959
|
+
/**
|
9960
|
+
* A list of variable and function names used in the directive's expression.
|
9961
|
+
*/
|
9962
|
+
#dependentIdentifiers;
|
9963
|
+
/**
|
9964
|
+
* The performance handler wrapper function.
|
9965
|
+
*/
|
9966
|
+
#handlerWrapper;
|
9967
|
+
/**
|
9968
|
+
* The PerformanceObserver instance.
|
9969
|
+
*/
|
9970
|
+
#performanceObserver;
|
9971
|
+
/**
|
9972
|
+
* @param context The context for parsing the directive.
|
9973
|
+
*/
|
9974
|
+
constructor(context) {
|
9975
|
+
this.#vNode = context.vNode;
|
9976
|
+
// Parse the expression to extract identifiers and create the handler wrapper
|
9977
|
+
const expression = context.attribute.value;
|
9978
|
+
if (expression) {
|
9979
|
+
this.#dependentIdentifiers = ExpressionUtils.extractIdentifiers(expression, context.vNode.vApplication.functionDependencies);
|
9980
|
+
this.#handlerWrapper = this.#createPerformanceHandlerWrapper(expression);
|
9981
|
+
}
|
9982
|
+
// Remove the directive attribute from the element
|
9983
|
+
this.#vNode.node.removeAttribute(context.attribute.name);
|
9984
|
+
}
|
9985
|
+
/**
|
9986
|
+
* @inheritdoc
|
9987
|
+
*/
|
9988
|
+
get name() {
|
9989
|
+
return StandardDirectiveName.V_PERFORMANCE;
|
9990
|
+
}
|
9991
|
+
/**
|
9992
|
+
* @inheritdoc
|
9993
|
+
*/
|
9994
|
+
get vNode() {
|
9995
|
+
return this.#vNode;
|
9996
|
+
}
|
9997
|
+
/**
|
9998
|
+
* @inheritdoc
|
9999
|
+
*/
|
10000
|
+
get needsAnchor() {
|
10001
|
+
return false;
|
10002
|
+
}
|
10003
|
+
/**
|
10004
|
+
* @inheritdoc
|
10005
|
+
*/
|
10006
|
+
get bindingsPreparer() {
|
10007
|
+
return undefined;
|
10008
|
+
}
|
10009
|
+
/**
|
10010
|
+
* @inheritdoc
|
10011
|
+
*/
|
10012
|
+
get domUpdater() {
|
10013
|
+
return undefined;
|
10014
|
+
}
|
10015
|
+
/**
|
10016
|
+
* @inheritdoc
|
10017
|
+
*/
|
10018
|
+
get templatize() {
|
10019
|
+
return false;
|
10020
|
+
}
|
10021
|
+
/**
|
10022
|
+
* @inheritdoc
|
10023
|
+
*/
|
10024
|
+
get dependentIdentifiers() {
|
10025
|
+
return this.#dependentIdentifiers ?? [];
|
10026
|
+
}
|
10027
|
+
/**
|
10028
|
+
* @inheritdoc
|
10029
|
+
*/
|
10030
|
+
get onMount() {
|
10031
|
+
return undefined;
|
10032
|
+
}
|
10033
|
+
/**
|
10034
|
+
* @inheritdoc
|
10035
|
+
*/
|
10036
|
+
get onMounted() {
|
10037
|
+
if (!this.#handlerWrapper) {
|
10038
|
+
return undefined;
|
10039
|
+
}
|
10040
|
+
const handler = this.#handlerWrapper;
|
10041
|
+
return () => {
|
10042
|
+
// Get options from :options.performance or :options directive
|
10043
|
+
let optionsDirective = this.#vNode.directiveManager?.optionsDirective('performance');
|
10044
|
+
// Evaluate the options expression
|
10045
|
+
let options;
|
10046
|
+
if (optionsDirective && optionsDirective.expression) {
|
10047
|
+
// Evaluate the options expression
|
10048
|
+
const identifiers = optionsDirective.dependentIdentifiers;
|
10049
|
+
const values = identifiers.map(id => this.#vNode.bindings?.get(id));
|
10050
|
+
const args = identifiers.join(", ");
|
10051
|
+
const funcBody = `return (${optionsDirective.expression});`;
|
10052
|
+
const func = new Function(args, funcBody);
|
10053
|
+
options = func(...values);
|
10054
|
+
}
|
10055
|
+
// Create PerformanceObserver and start observing
|
10056
|
+
// Note: The callback receives a third argument 'options' with droppedEntriesCount in modern browsers
|
10057
|
+
// TypeScript's type definition only includes 2 arguments, so we use type assertion
|
10058
|
+
this.#performanceObserver = new PerformanceObserver(((...args) => {
|
10059
|
+
const [entries, observer, callbackOptions] = args;
|
10060
|
+
handler(entries, observer, callbackOptions);
|
10061
|
+
}));
|
10062
|
+
// If no options provided, use default: observe marks and measures
|
10063
|
+
if (!options) {
|
10064
|
+
options = { entryTypes: ['mark', 'measure'] };
|
10065
|
+
}
|
10066
|
+
// Start observing with options
|
10067
|
+
this.#performanceObserver.observe(options);
|
10068
|
+
};
|
10069
|
+
}
|
10070
|
+
/**
|
10071
|
+
* @inheritdoc
|
10072
|
+
*/
|
10073
|
+
get onUpdate() {
|
10074
|
+
return undefined;
|
10075
|
+
}
|
10076
|
+
/**
|
10077
|
+
* @inheritdoc
|
10078
|
+
*/
|
10079
|
+
get onUpdated() {
|
10080
|
+
return undefined;
|
10081
|
+
}
|
10082
|
+
/**
|
10083
|
+
* @inheritdoc
|
10084
|
+
*/
|
10085
|
+
get onUnmount() {
|
10086
|
+
return undefined;
|
10087
|
+
}
|
10088
|
+
/**
|
10089
|
+
* @inheritdoc
|
10090
|
+
*/
|
10091
|
+
get onUnmounted() {
|
10092
|
+
return undefined;
|
10093
|
+
}
|
10094
|
+
/**
|
10095
|
+
* @inheritdoc
|
10096
|
+
*/
|
10097
|
+
destroy() {
|
10098
|
+
// Disconnect the PerformanceObserver when the directive is destroyed
|
10099
|
+
if (this.#performanceObserver) {
|
10100
|
+
this.#performanceObserver.disconnect();
|
10101
|
+
this.#performanceObserver = undefined;
|
10102
|
+
}
|
10103
|
+
}
|
10104
|
+
/**
|
10105
|
+
* Creates a wrapper function for performance handlers.
|
10106
|
+
* @param expression The expression string to evaluate.
|
10107
|
+
* @returns A function that handles the performance event.
|
10108
|
+
*/
|
10109
|
+
#createPerformanceHandlerWrapper(expression) {
|
10110
|
+
const identifiers = this.#dependentIdentifiers ?? [];
|
10111
|
+
const vNode = this.#vNode;
|
10112
|
+
// Return a function that handles the performance event with proper scope
|
10113
|
+
return (entries, observer, options) => {
|
10114
|
+
const bindings = vNode.bindings;
|
10115
|
+
const $ctx = {
|
10116
|
+
element: vNode.node,
|
10117
|
+
vnode: vNode,
|
10118
|
+
userData: vNode.userData
|
10119
|
+
};
|
10120
|
+
// If the expression is just a method name, call it with bindings as 'this'
|
10121
|
+
const trimmedExpr = expression.trim();
|
10122
|
+
if (identifiers.includes(trimmedExpr) && typeof bindings?.get(trimmedExpr) === 'function') {
|
10123
|
+
const methodName = trimmedExpr;
|
10124
|
+
const originalMethod = bindings?.get(methodName);
|
10125
|
+
// Call the method with bindings as 'this' context
|
10126
|
+
// Pass entries, observer, options, and $ctx as arguments
|
10127
|
+
return originalMethod(entries, observer, options, $ctx);
|
10128
|
+
}
|
10129
|
+
// For inline expressions, evaluate normally
|
10130
|
+
// Note: inline expressions receive entries, observer, options, and $ctx as parameters
|
10131
|
+
const values = identifiers.map(id => vNode.bindings?.get(id));
|
10132
|
+
const args = [...identifiers, 'entries', 'observer', 'options', '$ctx'].join(", ");
|
10133
|
+
const funcBody = `return (${expression});`;
|
10134
|
+
const func = new Function(args, funcBody);
|
10135
|
+
return func.call(bindings?.raw, ...values, entries, observer, options, $ctx);
|
10136
|
+
};
|
10137
|
+
}
|
10138
|
+
}
|
10139
|
+
|
9924
10140
|
// Copyright (c) 2025 MintJams Inc. Licensed under MIT License.
|
9925
10141
|
/**
|
9926
10142
|
* Directive for observing element resize events using ResizeObserver.
|
@@ -10351,7 +10567,9 @@ class VStandardDirectiveParser {
|
|
10351
10567
|
// v-resize
|
10352
10568
|
context.attribute.name === StandardDirectiveName.V_RESIZE ||
|
10353
10569
|
// v-intersection
|
10354
|
-
context.attribute.name === StandardDirectiveName.V_INTERSECTION
|
10570
|
+
context.attribute.name === StandardDirectiveName.V_INTERSECTION ||
|
10571
|
+
// v-performance
|
10572
|
+
context.attribute.name === StandardDirectiveName.V_PERFORMANCE) {
|
10355
10573
|
return true;
|
10356
10574
|
}
|
10357
10575
|
return false;
|
@@ -10398,6 +10616,10 @@ class VStandardDirectiveParser {
|
|
10398
10616
|
if (context.attribute.name === StandardDirectiveName.V_INTERSECTION) {
|
10399
10617
|
return new VIntersectionDirective(context);
|
10400
10618
|
}
|
10619
|
+
// v-performance
|
10620
|
+
if (context.attribute.name === StandardDirectiveName.V_PERFORMANCE) {
|
10621
|
+
return new VPerformanceDirective(context);
|
10622
|
+
}
|
10401
10623
|
throw new Error(`The attribute "${context.attribute.name}" cannot be parsed by ${this.name}.`);
|
10402
10624
|
}
|
10403
10625
|
}
|