UNPKG

2.02 kBJavaScriptView Raw
1import {
2 isFunction,
3 hasOwnProperty,
4 HINT_DISPOSE, HINT_DEPENDS, defineHint,
5 MESSAGE_NOT_FUNCTION, throwError
6} from "./util.js";
7
8/** Maximum queue length */
9var MAX_QUEUE = 2000;
10
11/** Is the queue being executed? */
12export var computedLock = false;
13/** Queue of computed functions to be called */
14export var computedQueue = [];
15/** Current index into `computedQueue` */
16export var computedI = 0;
17
18/**
19 * Throws an error indicating that the computed queue has overflowed
20 */
21function computedOverflow() {
22 var message = "Computed queue overflow! Last 10 functions in the queue:";
23
24 var length = computedQueue.length;
25 for (var i = length - 11; i < length; i++) {
26 var func = computedQueue[i];
27 message +=
28 "\n"
29 + (i + 1)
30 + ": "
31 + (func.name || "anonymous");
32 }
33
34 throwError(message, true);
35}
36
37/**
38 * Attempts to add a function to the computed queue, then attempts to lock and execute the computed queue
39 * @param func Function to queue
40 */
41export function computedNotify(func) {
42 if (hasOwnProperty(func, HINT_DISPOSE)) return;
43
44 // Only add to the queue if not already pending execution
45 if (computedQueue.lastIndexOf(func) >= computedI) return;
46 computedQueue.push(func);
47
48 // Make sure that the function in question has a depends hint
49 if (!hasOwnProperty(func, HINT_DEPENDS)) {
50 defineHint(func, HINT_DEPENDS, []);
51 }
52
53 // Attempt to lock and execute the queue
54 if (!computedLock) {
55 computedLock = true;
56
57 try {
58 for (; computedI < computedQueue.length; computedI++) {
59 // Indirectly call the function to avoid leaking `computedQueue` as `this`
60 (0, computedQueue[computedI])();
61 if (computedI > MAX_QUEUE) /* @__NOINLINE */ computedOverflow();
62 }
63 } finally {
64 computedLock = false;
65 computedQueue = [];
66 computedI = 0;
67 }
68 }
69}
70
71/** See lib/patella.d.ts */
72export function computed(func) {
73 if (!isFunction(func)) {
74 throwError(MESSAGE_NOT_FUNCTION);
75 }
76
77 computedNotify(func);
78 return func;
79}