mutts 1.0.1 → 1.0.3

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.
Files changed (111) hide show
  1. package/README.md +36 -6
  2. package/dist/chunks/_tslib-BgjropY9.js +81 -0
  3. package/dist/chunks/_tslib-BgjropY9.js.map +1 -0
  4. package/dist/chunks/_tslib-Mzh1rNsX.esm.js +75 -0
  5. package/dist/chunks/_tslib-Mzh1rNsX.esm.js.map +1 -0
  6. package/dist/chunks/{decorator-8qjFb7dw.js → decorator-DLvrD0UF.js} +103 -14
  7. package/dist/chunks/decorator-DLvrD0UF.js.map +1 -0
  8. package/dist/chunks/{decorator-AbRkXM5O.esm.js → decorator-DqiszP7i.esm.js} +100 -15
  9. package/dist/chunks/decorator-DqiszP7i.esm.js.map +1 -0
  10. package/dist/chunks/index-DzUDtFc7.esm.js +4841 -0
  11. package/dist/chunks/index-DzUDtFc7.esm.js.map +1 -0
  12. package/dist/chunks/index-HNVqPzjz.js +4891 -0
  13. package/dist/chunks/index-HNVqPzjz.js.map +1 -0
  14. package/dist/decorator.d.ts +57 -0
  15. package/dist/decorator.esm.js +1 -1
  16. package/dist/decorator.js +1 -1
  17. package/dist/destroyable.d.ts +43 -1
  18. package/dist/destroyable.esm.js +19 -1
  19. package/dist/destroyable.esm.js.map +1 -1
  20. package/dist/destroyable.js +19 -1
  21. package/dist/destroyable.js.map +1 -1
  22. package/dist/devtools/devtools.html +9 -0
  23. package/dist/devtools/devtools.js +5 -0
  24. package/dist/devtools/devtools.js.map +1 -0
  25. package/dist/devtools/manifest.json +8 -0
  26. package/dist/devtools/panel.css +72 -0
  27. package/dist/devtools/panel.html +31 -0
  28. package/dist/devtools/panel.js +13048 -0
  29. package/dist/devtools/panel.js.map +1 -0
  30. package/dist/eventful.d.ts +10 -1
  31. package/dist/eventful.esm.js +5 -27
  32. package/dist/eventful.esm.js.map +1 -1
  33. package/dist/eventful.js +15 -37
  34. package/dist/eventful.js.map +1 -1
  35. package/dist/index.d.ts +18 -14
  36. package/dist/index.esm.js +4 -3
  37. package/dist/index.esm.js.map +1 -1
  38. package/dist/index.js +44 -5
  39. package/dist/index.js.map +1 -1
  40. package/dist/indexable.d.ts +213 -1
  41. package/dist/indexable.esm.js +203 -3
  42. package/dist/indexable.esm.js.map +1 -1
  43. package/dist/indexable.js +204 -2
  44. package/dist/indexable.js.map +1 -1
  45. package/dist/mutts.umd.js +1 -1
  46. package/dist/mutts.umd.js.map +1 -1
  47. package/dist/mutts.umd.min.js +1 -1
  48. package/dist/mutts.umd.min.js.map +1 -1
  49. package/dist/promiseChain.d.ts +10 -0
  50. package/dist/promiseChain.esm.js +6 -0
  51. package/dist/promiseChain.esm.js.map +1 -1
  52. package/dist/promiseChain.js +6 -0
  53. package/dist/promiseChain.js.map +1 -1
  54. package/dist/reactive.d.ts +774 -33
  55. package/dist/reactive.esm.js +4 -1458
  56. package/dist/reactive.esm.js.map +1 -1
  57. package/dist/reactive.js +53 -1474
  58. package/dist/reactive.js.map +1 -1
  59. package/dist/std-decorators.d.ts +35 -0
  60. package/dist/std-decorators.esm.js +36 -1
  61. package/dist/std-decorators.esm.js.map +1 -1
  62. package/dist/std-decorators.js +36 -1
  63. package/dist/std-decorators.js.map +1 -1
  64. package/docs/ai/api-reference.md +133 -0
  65. package/docs/ai/manual.md +105 -0
  66. package/docs/iterableWeak.md +646 -0
  67. package/docs/mixin.md +229 -0
  68. package/docs/reactive/advanced.md +1280 -0
  69. package/docs/reactive/collections.md +767 -0
  70. package/docs/reactive/core.md +973 -0
  71. package/docs/reactive.md +21 -2688
  72. package/package.json +18 -5
  73. package/src/decorator.ts +266 -0
  74. package/src/destroyable.ts +199 -0
  75. package/src/eventful.ts +77 -0
  76. package/src/index.d.ts +9 -0
  77. package/src/index.ts +9 -0
  78. package/src/indexable.ts +484 -0
  79. package/src/introspection.ts +59 -0
  80. package/src/iterableWeak.ts +233 -0
  81. package/src/mixins.ts +123 -0
  82. package/src/promiseChain.ts +110 -0
  83. package/src/reactive/array.ts +414 -0
  84. package/src/reactive/change.ts +134 -0
  85. package/src/reactive/debug.ts +517 -0
  86. package/src/reactive/deep-touch.ts +268 -0
  87. package/src/reactive/deep-watch-state.ts +82 -0
  88. package/src/reactive/deep-watch.ts +168 -0
  89. package/src/reactive/effect-context.ts +94 -0
  90. package/src/reactive/effects.ts +1333 -0
  91. package/src/reactive/index.ts +75 -0
  92. package/src/reactive/interface.ts +223 -0
  93. package/src/reactive/map.ts +171 -0
  94. package/src/reactive/mapped.ts +130 -0
  95. package/src/reactive/memoize.ts +107 -0
  96. package/src/reactive/non-reactive-state.ts +49 -0
  97. package/src/reactive/non-reactive.ts +43 -0
  98. package/src/reactive/project.project.md +93 -0
  99. package/src/reactive/project.ts +335 -0
  100. package/src/reactive/proxy-state.ts +27 -0
  101. package/src/reactive/proxy.ts +285 -0
  102. package/src/reactive/record.ts +196 -0
  103. package/src/reactive/register.ts +421 -0
  104. package/src/reactive/set.ts +144 -0
  105. package/src/reactive/tracking.ts +101 -0
  106. package/src/reactive/types.ts +358 -0
  107. package/src/reactive/zone.ts +208 -0
  108. package/src/std-decorators.ts +217 -0
  109. package/src/utils.ts +117 -0
  110. package/dist/chunks/decorator-8qjFb7dw.js.map +0 -1
  111. package/dist/chunks/decorator-AbRkXM5O.esm.js.map +0 -1
@@ -1,24 +1,60 @@
1
+ /**
2
+ * Error thrown when decorator operations fail
3
+ */
1
4
  declare class DecoratorError extends Error {
2
5
  constructor(message: string);
3
6
  }
7
+ /**
8
+ * Legacy property decorator type for methods, getters, and setters
9
+ */
4
10
  type LegacyPropertyDecorator<T> = (target: T, name: string | symbol, descriptor: PropertyDescriptor) => any;
11
+ /**
12
+ * Legacy class decorator type
13
+ */
5
14
  type LegacyClassDecorator<T> = (target: T) => any;
15
+ /**
16
+ * Modern method decorator type
17
+ */
6
18
  type ModernMethodDecorator<T> = (target: T, context: ClassMethodDecoratorContext) => any;
19
+ /**
20
+ * Modern getter decorator type
21
+ */
7
22
  type ModernGetterDecorator<T> = (target: T, context: ClassGetterDecoratorContext) => any;
23
+ /**
24
+ * Modern setter decorator type
25
+ */
8
26
  type ModernSetterDecorator<T> = (target: T, context: ClassSetterDecoratorContext) => any;
27
+ /**
28
+ * Modern accessor decorator type
29
+ */
9
30
  type ModernAccessorDecorator<T> = (target: T, context: ClassAccessorDecoratorContext) => any;
31
+ /**
32
+ * Modern class decorator type
33
+ */
10
34
  type ModernClassDecorator<T> = (target: T, context: ClassDecoratorContext) => any;
11
35
  type DDMethod<T> = (original: (this: T, ...args: any[]) => any, name: PropertyKey) => ((this: T, ...args: any[]) => any) | void;
12
36
  type DDGetter<T> = (original: (this: T) => any, name: PropertyKey) => ((this: T) => any) | void;
13
37
  type DDSetter<T> = (original: (this: T, value: any) => void, name: PropertyKey) => ((this: T, value: any) => void) | void;
14
38
  type DDClass<T> = <Ctor extends new (...args: any[]) => T = new (...args: any[]) => T>(target: Ctor) => Ctor | void;
39
+ /**
40
+ * Description object for creating decorators that work with both Legacy and Modern decorator proposals
41
+ */
15
42
  interface DecoratorDescription<T> {
43
+ /** Handler for method decorators */
16
44
  method?: DDMethod<T>;
45
+ /** Handler for class decorators */
17
46
  class?: DDClass<T>;
47
+ /** Handler for getter decorators */
18
48
  getter?: DDGetter<T>;
49
+ /** Handler for setter decorators */
19
50
  setter?: DDSetter<T>;
51
+ /** Default handler for any decorator type not explicitly defined */
20
52
  default?: (...args: any[]) => any;
21
53
  }
54
+ /**
55
+ * Type for decorators that work with both Legacy and Modern decorator proposals
56
+ * Automatically infers the correct decorator type based on the description
57
+ */
22
58
  type Decorator<T, Description extends DecoratorDescription<T>> = (Description extends {
23
59
  method: DDMethod<T>;
24
60
  } ? LegacyPropertyDecorator<T> & ModernMethodDecorator<T> : unknown) & (Description extends {
@@ -30,6 +66,9 @@ type Decorator<T, Description extends DecoratorDescription<T>> = (Description ex
30
66
  } ? LegacyPropertyDecorator<T> & ModernSetterDecorator<T> & ModernAccessorDecorator<T> : unknown) & (Description extends {
31
67
  default: infer Signature;
32
68
  } ? Signature : unknown);
69
+ /**
70
+ * Factory type for creating decorators that work with both Legacy and Modern decorator proposals
71
+ */
33
72
  type DecoratorFactory<T> = <Description extends DecoratorDescription<T>>(description: Description) => (Description extends {
34
73
  method: DDMethod<T>;
35
74
  } ? LegacyPropertyDecorator<T> & ModernMethodDecorator<T> : unknown) & (Description extends {
@@ -41,9 +80,27 @@ type DecoratorFactory<T> = <Description extends DecoratorDescription<T>>(descrip
41
80
  } ? LegacyPropertyDecorator<T> & ModernSetterDecorator<T> & ModernAccessorDecorator<T> : unknown) & (Description extends {
42
81
  default: infer Signature;
43
82
  } ? Signature : unknown);
83
+ /**
84
+ * Creates a decorator that works with Legacy decorator proposals
85
+ * @param description - The decorator description object
86
+ * @returns A decorator function compatible with Legacy decorators
87
+ */
44
88
  declare function legacyDecorator<T = any>(description: DecoratorDescription<T>): any;
89
+ /**
90
+ * Creates a decorator that works with Modern decorator proposals
91
+ * @param description - The decorator description object
92
+ * @returns A decorator function compatible with Modern decorators
93
+ */
45
94
  declare function modernDecorator<T = any>(description: DecoratorDescription<T>): any;
95
+ /**
96
+ * Main decorator factory that automatically detects and works with both Legacy and Modern decorator proposals
97
+ * @param description - The decorator description object
98
+ * @returns A decorator that works in both Legacy and Modern environments
99
+ */
46
100
  declare const decorator: DecoratorFactory<any>;
101
+ /**
102
+ * Generic class decorator type that works with both Legacy and Modern decorator proposals
103
+ */
47
104
  type GenericClassDecorator<T> = LegacyClassDecorator<abstract new (...args: any[]) => T> & ModernClassDecorator<abstract new (...args: any[]) => T>;
48
105
 
49
106
  export { DecoratorError, decorator, legacyDecorator, modernDecorator };
@@ -1,2 +1,2 @@
1
- export { D as DecoratorError, d as decorator, l as legacyDecorator, m as modernDecorator } from './chunks/decorator-AbRkXM5O.esm.js';
1
+ export { D as DecoratorError, d as decorator, l as legacyDecorator, m as modernDecorator } from './chunks/decorator-DqiszP7i.esm.js';
2
2
  //# sourceMappingURL=decorator.esm.js.map
package/dist/decorator.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var decorator = require('./chunks/decorator-8qjFb7dw.js');
3
+ var decorator = require('./chunks/decorator-DLvrD0UF.js');
4
4
 
5
5
 
6
6
 
@@ -1,7 +1,16 @@
1
1
  import { LegacyPropertyDecorator, ModernSetterDecorator, ModernAccessorDecorator } from './decorator.js';
2
2
 
3
+ /**
4
+ * Symbol for marking destructor methods
5
+ */
3
6
  declare const destructor: unique symbol;
7
+ /**
8
+ * Symbol for accessing allocated values in destroyable objects
9
+ */
4
10
  declare const allocatedValues: unique symbol;
11
+ /**
12
+ * Error thrown when attempting to access a destroyed object
13
+ */
5
14
  declare class DestructionError extends Error {
6
15
  static throw<_T = void>(msg: string): () => never;
7
16
  constructor(msg: string);
@@ -13,32 +22,65 @@ declare abstract class AbstractDestroyable<Allocated> {
13
22
  interface Destructor<Allocated> {
14
23
  destructor(allocated: Allocated): void;
15
24
  }
16
- declare function Destroyable<T extends new (...args: any[]) => any, Allocated extends Partial<typeof this>>(base: T, destructorObj: Destructor<Allocated>): (new (...args: ConstructorParameters<T>) => InstanceType<T> & {
25
+ /**
26
+ * Creates a destroyable class with a base class and destructor object
27
+ * @param base - The base class to extend
28
+ * @param destructorObj - Object containing the destructor method
29
+ * @returns A destroyable class with static destroy and isDestroyable methods
30
+ */
31
+ declare function Destroyable<T extends new (...args: any[]) => any, Allocated extends Partial<InstanceType<T>>>(base: T, destructorObj: Destructor<Allocated>): (new (...args: ConstructorParameters<T>) => InstanceType<T> & {
17
32
  [allocatedValues]: Allocated;
18
33
  }) & {
19
34
  destroy(obj: InstanceType<T>): boolean;
20
35
  isDestroyable(obj: InstanceType<T>): boolean;
21
36
  };
37
+ /**
38
+ * Creates a destroyable class with only a destructor object (no base class)
39
+ * @param destructorObj - Object containing the destructor method
40
+ * @returns A destroyable class with static destroy and isDestroyable methods
41
+ */
22
42
  declare function Destroyable<Allocated extends Record<PropertyKey, any> = Record<PropertyKey, any>>(destructorObj: Destructor<Allocated>): (new () => {
23
43
  [allocatedValues]: Allocated;
24
44
  }) & {
25
45
  destroy(obj: any): boolean;
26
46
  isDestroyable(obj: any): boolean;
27
47
  };
48
+ /**
49
+ * Creates a destroyable class with a base class (requires [destructor] method)
50
+ * @param base - The base class to extend
51
+ * @returns A destroyable class with static destroy and isDestroyable methods
52
+ */
28
53
  declare function Destroyable<T extends new (...args: any[]) => any, Allocated extends Record<PropertyKey, any> = Record<PropertyKey, any>>(base: T): (new (...args: ConstructorParameters<T>) => AbstractDestroyable<Allocated> & InstanceType<T> & {
29
54
  [allocatedValues]: Allocated;
30
55
  }) & {
31
56
  destroy(obj: InstanceType<T>): boolean;
32
57
  isDestroyable(obj: InstanceType<T>): boolean;
33
58
  };
59
+ /**
60
+ * Creates an abstract destroyable base class
61
+ * @returns An abstract destroyable class with static destroy and isDestroyable methods
62
+ */
34
63
  declare function Destroyable<Allocated extends Record<PropertyKey, any> = Record<PropertyKey, any>>(): abstract new () => (AbstractDestroyable<Allocated> & {
35
64
  [allocatedValues]: Allocated;
36
65
  }) & {
37
66
  destroy(obj: any): boolean;
38
67
  isDestroyable(obj: any): boolean;
39
68
  };
69
+ /**
70
+ * Decorator that marks properties to be stored in the allocated object and passed to the destructor
71
+ * Use with accessor properties or explicit get/set pairs
72
+ */
40
73
  declare const allocated: LegacyPropertyDecorator<any> & ModernSetterDecorator<any> & ModernAccessorDecorator<any>;
74
+ /**
75
+ * Registers a callback to be called when an object is garbage collected
76
+ * @param cb - The callback function to execute on garbage collection
77
+ * @returns The object whose reference can be collected
78
+ */
41
79
  declare function callOnGC(cb: () => void): () => void;
80
+ /**
81
+ * Context Manager Protocol for `using` statement integration
82
+ * Provides automatic resource cleanup when used with the `using` statement
83
+ */
42
84
  interface ContextManager<T = any> {
43
85
  [Symbol.dispose](): void;
44
86
  value?: T;
@@ -1,9 +1,18 @@
1
- import { d as decorator } from './chunks/decorator-AbRkXM5O.esm.js';
1
+ import { d as decorator } from './chunks/decorator-DqiszP7i.esm.js';
2
2
 
3
3
  // Integrated with `using` statement via Symbol.dispose
4
4
  const fr = new FinalizationRegistry((f) => f());
5
+ /**
6
+ * Symbol for marking destructor methods
7
+ */
5
8
  const destructor = Symbol('destructor');
9
+ /**
10
+ * Symbol for accessing allocated values in destroyable objects
11
+ */
6
12
  const allocatedValues = Symbol('allocated');
13
+ /**
14
+ * Error thrown when attempting to access a destroyed object
15
+ */
7
16
  class DestructionError extends Error {
8
17
  static throw(msg) {
9
18
  return () => {
@@ -67,6 +76,10 @@ function Destroyable(base, destructorObj) {
67
76
  _a.destructors = new WeakMap(),
68
77
  _a;
69
78
  }
79
+ /**
80
+ * Decorator that marks properties to be stored in the allocated object and passed to the destructor
81
+ * Use with accessor properties or explicit get/set pairs
82
+ */
70
83
  const allocated = decorator({
71
84
  setter(original, propertyKey) {
72
85
  return function (value) {
@@ -75,6 +88,11 @@ const allocated = decorator({
75
88
  };
76
89
  },
77
90
  });
91
+ /**
92
+ * Registers a callback to be called when an object is garbage collected
93
+ * @param cb - The callback function to execute on garbage collection
94
+ * @returns The object whose reference can be collected
95
+ */
78
96
  function callOnGC(cb) {
79
97
  let called = false;
80
98
  const forward = () => {
@@ -1 +1 @@
1
- {"version":3,"file":"destroyable.esm.js","sources":["../src/destroyable.ts"],"sourcesContent":["import { decorator } from './decorator'\n\n// Integrated with `using` statement via Symbol.dispose\nconst fr = new FinalizationRegistry<() => void>((f) => f())\nexport const destructor = Symbol('destructor')\nexport const allocatedValues = Symbol('allocated')\nexport class DestructionError extends Error {\n\tstatic throw<_T = void>(msg: string) {\n\t\treturn () => {\n\t\t\tthrow new DestructionError(msg)\n\t\t}\n\t}\n\tconstructor(msg: string) {\n\t\tsuper(`Object is destroyed. ${msg}`)\n\t\tthis.name = 'DestroyedAccessError'\n\t}\n}\nconst destroyedHandler = {\n\t[Symbol.toStringTag]: 'MutTs Destroyable',\n\tget: DestructionError.throw('Cannot access destroyed object'),\n\tset: DestructionError.throw('Cannot access destroyed object'),\n} as const\n\nabstract class AbstractDestroyable<Allocated> {\n\tabstract [destructor](allocated: Allocated): void\n\t[Symbol.dispose](): void {\n\t\tthis[destructor](this as unknown as Allocated)\n\t}\n}\n\ninterface Destructor<Allocated> {\n\tdestructor(allocated: Allocated): void\n}\n\nexport function Destroyable<\n\tT extends new (\n\t\t...args: any[]\n\t) => any,\n\tAllocated extends Partial<typeof this>,\n>(\n\tbase: T,\n\tdestructorObj: Destructor<Allocated>\n): (new (\n\t...args: ConstructorParameters<T>\n) => InstanceType<T> & { [allocatedValues]: Allocated }) & {\n\tdestroy(obj: InstanceType<T>): boolean\n\tisDestroyable(obj: InstanceType<T>): boolean\n}\n\nexport function Destroyable<Allocated extends Record<PropertyKey, any> = Record<PropertyKey, any>>(\n\tdestructorObj: Destructor<Allocated>\n): (new () => { [allocatedValues]: Allocated }) & {\n\tdestroy(obj: any): boolean\n\tisDestroyable(obj: any): boolean\n}\n\nexport function Destroyable<\n\tT extends new (\n\t\t...args: any[]\n\t) => any,\n\tAllocated extends Record<PropertyKey, any> = Record<PropertyKey, any>,\n>(\n\tbase: T\n): (new (\n\t...args: ConstructorParameters<T>\n) => AbstractDestroyable<Allocated> & InstanceType<T> & { [allocatedValues]: Allocated }) & {\n\tdestroy(obj: InstanceType<T>): boolean\n\tisDestroyable(obj: InstanceType<T>): boolean\n}\n\nexport function Destroyable<\n\tAllocated extends Record<PropertyKey, any> = Record<PropertyKey, any>,\n>(): abstract new () => (AbstractDestroyable<Allocated> & {\n\t[allocatedValues]: Allocated\n}) & {\n\tdestroy(obj: any): boolean\n\tisDestroyable(obj: any): boolean\n}\n\nexport function Destroyable<\n\tT extends new (\n\t\t...args: any[]\n\t) => any,\n\tAllocated extends Record<PropertyKey, any> = Record<PropertyKey, any>,\n>(base?: T | Destructor<Allocated>, destructorObj?: Destructor<Allocated>) {\n\tif (base && typeof base !== 'function') {\n\t\tdestructorObj = base as Destructor<Allocated>\n\t\tbase = undefined\n\t}\n\tif (!base) {\n\t\tbase = class {} as T\n\t}\n\n\treturn class Destroyable extends (base as T) {\n\t\tstatic readonly destructors = new WeakMap<any, () => void>()\n\t\tstatic destroy(obj: Destroyable) {\n\t\t\tconst destructor = Destroyable.destructors.get(obj)\n\t\t\tif (!destructor) return false\n\t\t\tfr.unregister(obj)\n\t\t\tDestroyable.destructors.delete(obj)\n\t\t\tObject.setPrototypeOf(obj, new Proxy({}, destroyedHandler))\n\t\t\t// Clear all own properties\n\t\t\tfor (const key of Object.getOwnPropertyNames(obj)) {\n\t\t\t\tdelete (obj as any)[key]\n\t\t\t}\n\t\t\tdestructor()\n\t\t\treturn true\n\t\t}\n\t\tstatic isDestroyable(obj: Destroyable) {\n\t\t\treturn Destroyable.destructors.has(obj)\n\t\t}\n\n\t\tdeclare [forwardProperties]: PropertyKey[]\n\t\treadonly [allocatedValues]: Allocated\n\t\tconstructor(...args: any[]) {\n\t\t\tsuper(...args)\n\t\t\tconst allocated = {} as Allocated\n\t\t\tthis[allocatedValues] = allocated\n\t\t\t// @ts-expect-error `this` is an AbstractDestroyable\n\t\t\tconst myDestructor = destructorObj?.destructor ?? this[destructor]\n\t\t\tif (!myDestructor) {\n\t\t\t\tthrow new DestructionError('Destructor is not defined')\n\t\t\t}\n\t\t\tfunction destruction() {\n\t\t\t\tmyDestructor(allocated)\n\t\t\t}\n\t\t\tDestroyable.destructors.set(this, destruction)\n\t\t\tfr.register(this, destruction, this)\n\t\t}\n\t}\n}\n\nconst forwardProperties = Symbol('forwardProperties')\nexport const allocated = decorator({\n\tsetter(original, propertyKey) {\n\t\treturn function (value) {\n\t\t\tthis[allocatedValues][propertyKey] = value\n\t\t\treturn original.call(this, value)\n\t\t}\n\t},\n})\n\nexport function callOnGC(cb: () => void) {\n\tlet called = false\n\tconst forward = () => {\n\t\tif (called) return\n\t\tcalled = true\n\t\tcb()\n\t}\n\tfr.register(forward, cb, cb)\n\treturn forward\n}\n\n// Context Manager Protocol for `with` statement integration\nexport interface ContextManager<T = any> {\n\t[Symbol.dispose](): void\n\tvalue?: T\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"destroyable.esm.js","sources":["../src/destroyable.ts"],"sourcesContent":["import { decorator } from './decorator'\n\n// Integrated with `using` statement via Symbol.dispose\nconst fr = new FinalizationRegistry<() => void>((f) => f())\n/**\n * Symbol for marking destructor methods\n */\nexport const destructor = Symbol('destructor')\n/**\n * Symbol for accessing allocated values in destroyable objects\n */\nexport const allocatedValues = Symbol('allocated')\n/**\n * Error thrown when attempting to access a destroyed object\n */\nexport class DestructionError extends Error {\n\tstatic throw<_T = void>(msg: string) {\n\t\treturn () => {\n\t\t\tthrow new DestructionError(msg)\n\t\t}\n\t}\n\tconstructor(msg: string) {\n\t\tsuper(`Object is destroyed. ${msg}`)\n\t\tthis.name = 'DestroyedAccessError'\n\t}\n}\nconst destroyedHandler = {\n\t[Symbol.toStringTag]: 'MutTs Destroyable',\n\tget: DestructionError.throw('Cannot access destroyed object'),\n\tset: DestructionError.throw('Cannot access destroyed object'),\n} as const\n\nabstract class AbstractDestroyable<Allocated> {\n\tabstract [destructor](allocated: Allocated): void\n\t[Symbol.dispose](): void {\n\t\tthis[destructor](this as unknown as Allocated)\n\t}\n}\n\ninterface Destructor<Allocated> {\n\tdestructor(allocated: Allocated): void\n}\n\n/**\n * Creates a destroyable class with a base class and destructor object\n * @param base - The base class to extend\n * @param destructorObj - Object containing the destructor method\n * @returns A destroyable class with static destroy and isDestroyable methods\n */\nexport function Destroyable<\n\tT extends new (\n\t\t...args: any[]\n\t) => any,\n\tAllocated extends Partial<InstanceType<T>>,\n>(\n\tbase: T,\n\tdestructorObj: Destructor<Allocated>\n): (new (\n\t...args: ConstructorParameters<T>\n) => InstanceType<T> & { [allocatedValues]: Allocated }) & {\n\tdestroy(obj: InstanceType<T>): boolean\n\tisDestroyable(obj: InstanceType<T>): boolean\n}\n\n/**\n * Creates a destroyable class with only a destructor object (no base class)\n * @param destructorObj - Object containing the destructor method\n * @returns A destroyable class with static destroy and isDestroyable methods\n */\nexport function Destroyable<Allocated extends Record<PropertyKey, any> = Record<PropertyKey, any>>(\n\tdestructorObj: Destructor<Allocated>\n): (new () => { [allocatedValues]: Allocated }) & {\n\tdestroy(obj: any): boolean\n\tisDestroyable(obj: any): boolean\n}\n\n/**\n * Creates a destroyable class with a base class (requires [destructor] method)\n * @param base - The base class to extend\n * @returns A destroyable class with static destroy and isDestroyable methods\n */\nexport function Destroyable<\n\tT extends new (\n\t\t...args: any[]\n\t) => any,\n\tAllocated extends Record<PropertyKey, any> = Record<PropertyKey, any>,\n>(\n\tbase: T\n): (new (\n\t...args: ConstructorParameters<T>\n) => AbstractDestroyable<Allocated> & InstanceType<T> & { [allocatedValues]: Allocated }) & {\n\tdestroy(obj: InstanceType<T>): boolean\n\tisDestroyable(obj: InstanceType<T>): boolean\n}\n\n/**\n * Creates an abstract destroyable base class\n * @returns An abstract destroyable class with static destroy and isDestroyable methods\n */\nexport function Destroyable<\n\tAllocated extends Record<PropertyKey, any> = Record<PropertyKey, any>,\n>(): abstract new () => (AbstractDestroyable<Allocated> & {\n\t[allocatedValues]: Allocated\n}) & {\n\tdestroy(obj: any): boolean\n\tisDestroyable(obj: any): boolean\n}\n\nexport function Destroyable<\n\tT extends new (\n\t\t...args: any[]\n\t) => any,\n\tAllocated extends Record<PropertyKey, any> = Record<PropertyKey, any>,\n>(base?: T | Destructor<Allocated>, destructorObj?: Destructor<Allocated>) {\n\tif (base && typeof base !== 'function') {\n\t\tdestructorObj = base as Destructor<Allocated>\n\t\tbase = undefined\n\t}\n\tif (!base) {\n\t\tbase = class {} as T\n\t}\n\n\treturn class Destroyable extends (base as T) {\n\t\tstatic readonly destructors = new WeakMap<any, () => void>()\n\t\tstatic destroy(obj: Destroyable) {\n\t\t\tconst destructor = Destroyable.destructors.get(obj)\n\t\t\tif (!destructor) return false\n\t\t\tfr.unregister(obj)\n\t\t\tDestroyable.destructors.delete(obj)\n\t\t\tObject.setPrototypeOf(obj, new Proxy({}, destroyedHandler))\n\t\t\t// Clear all own properties\n\t\t\tfor (const key of Object.getOwnPropertyNames(obj)) {\n\t\t\t\tdelete (obj as any)[key]\n\t\t\t}\n\t\t\tdestructor()\n\t\t\treturn true\n\t\t}\n\t\tstatic isDestroyable(obj: Destroyable) {\n\t\t\treturn Destroyable.destructors.has(obj)\n\t\t}\n\n\t\tdeclare [forwardProperties]: PropertyKey[]\n\t\treadonly [allocatedValues]: Allocated\n\t\tconstructor(...args: any[]) {\n\t\t\tsuper(...args)\n\t\t\tconst allocated = {} as Allocated\n\t\t\tthis[allocatedValues] = allocated\n\t\t\t// @ts-expect-error `this` is an AbstractDestroyable\n\t\t\tconst myDestructor = destructorObj?.destructor ?? this[destructor]\n\t\t\tif (!myDestructor) {\n\t\t\t\tthrow new DestructionError('Destructor is not defined')\n\t\t\t}\n\t\t\tfunction destruction() {\n\t\t\t\tmyDestructor(allocated)\n\t\t\t}\n\t\t\tDestroyable.destructors.set(this, destruction)\n\t\t\tfr.register(this, destruction, this)\n\t\t}\n\t}\n}\n\nconst forwardProperties = Symbol('forwardProperties')\n/**\n * Decorator that marks properties to be stored in the allocated object and passed to the destructor\n * Use with accessor properties or explicit get/set pairs\n */\nexport const allocated = decorator({\n\tsetter(original, propertyKey) {\n\t\treturn function (value) {\n\t\t\tthis[allocatedValues][propertyKey] = value\n\t\t\treturn original.call(this, value)\n\t\t}\n\t},\n})\n\n/**\n * Registers a callback to be called when an object is garbage collected\n * @param cb - The callback function to execute on garbage collection\n * @returns The object whose reference can be collected\n */\nexport function callOnGC(cb: () => void) {\n\tlet called = false\n\tconst forward = () => {\n\t\tif (called) return\n\t\tcalled = true\n\t\tcb()\n\t}\n\tfr.register(forward, cb, cb)\n\treturn forward\n}\n\n/**\n * Context Manager Protocol for `using` statement integration\n * Provides automatic resource cleanup when used with the `using` statement\n */\nexport interface ContextManager<T = any> {\n\t[Symbol.dispose](): void\n\tvalue?: T\n}\n"],"names":[],"mappings":"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"}
@@ -1,11 +1,20 @@
1
1
  'use strict';
2
2
 
3
- var decorator = require('./chunks/decorator-8qjFb7dw.js');
3
+ var decorator = require('./chunks/decorator-DLvrD0UF.js');
4
4
 
5
5
  // Integrated with `using` statement via Symbol.dispose
6
6
  const fr = new FinalizationRegistry((f) => f());
7
+ /**
8
+ * Symbol for marking destructor methods
9
+ */
7
10
  const destructor = Symbol('destructor');
11
+ /**
12
+ * Symbol for accessing allocated values in destroyable objects
13
+ */
8
14
  const allocatedValues = Symbol('allocated');
15
+ /**
16
+ * Error thrown when attempting to access a destroyed object
17
+ */
9
18
  class DestructionError extends Error {
10
19
  static throw(msg) {
11
20
  return () => {
@@ -69,6 +78,10 @@ function Destroyable(base, destructorObj) {
69
78
  _a.destructors = new WeakMap(),
70
79
  _a;
71
80
  }
81
+ /**
82
+ * Decorator that marks properties to be stored in the allocated object and passed to the destructor
83
+ * Use with accessor properties or explicit get/set pairs
84
+ */
72
85
  const allocated = decorator.decorator({
73
86
  setter(original, propertyKey) {
74
87
  return function (value) {
@@ -77,6 +90,11 @@ const allocated = decorator.decorator({
77
90
  };
78
91
  },
79
92
  });
93
+ /**
94
+ * Registers a callback to be called when an object is garbage collected
95
+ * @param cb - The callback function to execute on garbage collection
96
+ * @returns The object whose reference can be collected
97
+ */
80
98
  function callOnGC(cb) {
81
99
  let called = false;
82
100
  const forward = () => {
@@ -1 +1 @@
1
- {"version":3,"file":"destroyable.js","sources":["../src/destroyable.ts"],"sourcesContent":["import { decorator } from './decorator'\n\n// Integrated with `using` statement via Symbol.dispose\nconst fr = new FinalizationRegistry<() => void>((f) => f())\nexport const destructor = Symbol('destructor')\nexport const allocatedValues = Symbol('allocated')\nexport class DestructionError extends Error {\n\tstatic throw<_T = void>(msg: string) {\n\t\treturn () => {\n\t\t\tthrow new DestructionError(msg)\n\t\t}\n\t}\n\tconstructor(msg: string) {\n\t\tsuper(`Object is destroyed. ${msg}`)\n\t\tthis.name = 'DestroyedAccessError'\n\t}\n}\nconst destroyedHandler = {\n\t[Symbol.toStringTag]: 'MutTs Destroyable',\n\tget: DestructionError.throw('Cannot access destroyed object'),\n\tset: DestructionError.throw('Cannot access destroyed object'),\n} as const\n\nabstract class AbstractDestroyable<Allocated> {\n\tabstract [destructor](allocated: Allocated): void\n\t[Symbol.dispose](): void {\n\t\tthis[destructor](this as unknown as Allocated)\n\t}\n}\n\ninterface Destructor<Allocated> {\n\tdestructor(allocated: Allocated): void\n}\n\nexport function Destroyable<\n\tT extends new (\n\t\t...args: any[]\n\t) => any,\n\tAllocated extends Partial<typeof this>,\n>(\n\tbase: T,\n\tdestructorObj: Destructor<Allocated>\n): (new (\n\t...args: ConstructorParameters<T>\n) => InstanceType<T> & { [allocatedValues]: Allocated }) & {\n\tdestroy(obj: InstanceType<T>): boolean\n\tisDestroyable(obj: InstanceType<T>): boolean\n}\n\nexport function Destroyable<Allocated extends Record<PropertyKey, any> = Record<PropertyKey, any>>(\n\tdestructorObj: Destructor<Allocated>\n): (new () => { [allocatedValues]: Allocated }) & {\n\tdestroy(obj: any): boolean\n\tisDestroyable(obj: any): boolean\n}\n\nexport function Destroyable<\n\tT extends new (\n\t\t...args: any[]\n\t) => any,\n\tAllocated extends Record<PropertyKey, any> = Record<PropertyKey, any>,\n>(\n\tbase: T\n): (new (\n\t...args: ConstructorParameters<T>\n) => AbstractDestroyable<Allocated> & InstanceType<T> & { [allocatedValues]: Allocated }) & {\n\tdestroy(obj: InstanceType<T>): boolean\n\tisDestroyable(obj: InstanceType<T>): boolean\n}\n\nexport function Destroyable<\n\tAllocated extends Record<PropertyKey, any> = Record<PropertyKey, any>,\n>(): abstract new () => (AbstractDestroyable<Allocated> & {\n\t[allocatedValues]: Allocated\n}) & {\n\tdestroy(obj: any): boolean\n\tisDestroyable(obj: any): boolean\n}\n\nexport function Destroyable<\n\tT extends new (\n\t\t...args: any[]\n\t) => any,\n\tAllocated extends Record<PropertyKey, any> = Record<PropertyKey, any>,\n>(base?: T | Destructor<Allocated>, destructorObj?: Destructor<Allocated>) {\n\tif (base && typeof base !== 'function') {\n\t\tdestructorObj = base as Destructor<Allocated>\n\t\tbase = undefined\n\t}\n\tif (!base) {\n\t\tbase = class {} as T\n\t}\n\n\treturn class Destroyable extends (base as T) {\n\t\tstatic readonly destructors = new WeakMap<any, () => void>()\n\t\tstatic destroy(obj: Destroyable) {\n\t\t\tconst destructor = Destroyable.destructors.get(obj)\n\t\t\tif (!destructor) return false\n\t\t\tfr.unregister(obj)\n\t\t\tDestroyable.destructors.delete(obj)\n\t\t\tObject.setPrototypeOf(obj, new Proxy({}, destroyedHandler))\n\t\t\t// Clear all own properties\n\t\t\tfor (const key of Object.getOwnPropertyNames(obj)) {\n\t\t\t\tdelete (obj as any)[key]\n\t\t\t}\n\t\t\tdestructor()\n\t\t\treturn true\n\t\t}\n\t\tstatic isDestroyable(obj: Destroyable) {\n\t\t\treturn Destroyable.destructors.has(obj)\n\t\t}\n\n\t\tdeclare [forwardProperties]: PropertyKey[]\n\t\treadonly [allocatedValues]: Allocated\n\t\tconstructor(...args: any[]) {\n\t\t\tsuper(...args)\n\t\t\tconst allocated = {} as Allocated\n\t\t\tthis[allocatedValues] = allocated\n\t\t\t// @ts-expect-error `this` is an AbstractDestroyable\n\t\t\tconst myDestructor = destructorObj?.destructor ?? this[destructor]\n\t\t\tif (!myDestructor) {\n\t\t\t\tthrow new DestructionError('Destructor is not defined')\n\t\t\t}\n\t\t\tfunction destruction() {\n\t\t\t\tmyDestructor(allocated)\n\t\t\t}\n\t\t\tDestroyable.destructors.set(this, destruction)\n\t\t\tfr.register(this, destruction, this)\n\t\t}\n\t}\n}\n\nconst forwardProperties = Symbol('forwardProperties')\nexport const allocated = decorator({\n\tsetter(original, propertyKey) {\n\t\treturn function (value) {\n\t\t\tthis[allocatedValues][propertyKey] = value\n\t\t\treturn original.call(this, value)\n\t\t}\n\t},\n})\n\nexport function callOnGC(cb: () => void) {\n\tlet called = false\n\tconst forward = () => {\n\t\tif (called) return\n\t\tcalled = true\n\t\tcb()\n\t}\n\tfr.register(forward, cb, cb)\n\treturn forward\n}\n\n// Context Manager Protocol for `with` statement integration\nexport interface ContextManager<T = any> {\n\t[Symbol.dispose](): void\n\tvalue?: T\n}\n"],"names":["decorator"],"mappings":"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"}
1
+ {"version":3,"file":"destroyable.js","sources":["../src/destroyable.ts"],"sourcesContent":["import { decorator } from './decorator'\n\n// Integrated with `using` statement via Symbol.dispose\nconst fr = new FinalizationRegistry<() => void>((f) => f())\n/**\n * Symbol for marking destructor methods\n */\nexport const destructor = Symbol('destructor')\n/**\n * Symbol for accessing allocated values in destroyable objects\n */\nexport const allocatedValues = Symbol('allocated')\n/**\n * Error thrown when attempting to access a destroyed object\n */\nexport class DestructionError extends Error {\n\tstatic throw<_T = void>(msg: string) {\n\t\treturn () => {\n\t\t\tthrow new DestructionError(msg)\n\t\t}\n\t}\n\tconstructor(msg: string) {\n\t\tsuper(`Object is destroyed. ${msg}`)\n\t\tthis.name = 'DestroyedAccessError'\n\t}\n}\nconst destroyedHandler = {\n\t[Symbol.toStringTag]: 'MutTs Destroyable',\n\tget: DestructionError.throw('Cannot access destroyed object'),\n\tset: DestructionError.throw('Cannot access destroyed object'),\n} as const\n\nabstract class AbstractDestroyable<Allocated> {\n\tabstract [destructor](allocated: Allocated): void\n\t[Symbol.dispose](): void {\n\t\tthis[destructor](this as unknown as Allocated)\n\t}\n}\n\ninterface Destructor<Allocated> {\n\tdestructor(allocated: Allocated): void\n}\n\n/**\n * Creates a destroyable class with a base class and destructor object\n * @param base - The base class to extend\n * @param destructorObj - Object containing the destructor method\n * @returns A destroyable class with static destroy and isDestroyable methods\n */\nexport function Destroyable<\n\tT extends new (\n\t\t...args: any[]\n\t) => any,\n\tAllocated extends Partial<InstanceType<T>>,\n>(\n\tbase: T,\n\tdestructorObj: Destructor<Allocated>\n): (new (\n\t...args: ConstructorParameters<T>\n) => InstanceType<T> & { [allocatedValues]: Allocated }) & {\n\tdestroy(obj: InstanceType<T>): boolean\n\tisDestroyable(obj: InstanceType<T>): boolean\n}\n\n/**\n * Creates a destroyable class with only a destructor object (no base class)\n * @param destructorObj - Object containing the destructor method\n * @returns A destroyable class with static destroy and isDestroyable methods\n */\nexport function Destroyable<Allocated extends Record<PropertyKey, any> = Record<PropertyKey, any>>(\n\tdestructorObj: Destructor<Allocated>\n): (new () => { [allocatedValues]: Allocated }) & {\n\tdestroy(obj: any): boolean\n\tisDestroyable(obj: any): boolean\n}\n\n/**\n * Creates a destroyable class with a base class (requires [destructor] method)\n * @param base - The base class to extend\n * @returns A destroyable class with static destroy and isDestroyable methods\n */\nexport function Destroyable<\n\tT extends new (\n\t\t...args: any[]\n\t) => any,\n\tAllocated extends Record<PropertyKey, any> = Record<PropertyKey, any>,\n>(\n\tbase: T\n): (new (\n\t...args: ConstructorParameters<T>\n) => AbstractDestroyable<Allocated> & InstanceType<T> & { [allocatedValues]: Allocated }) & {\n\tdestroy(obj: InstanceType<T>): boolean\n\tisDestroyable(obj: InstanceType<T>): boolean\n}\n\n/**\n * Creates an abstract destroyable base class\n * @returns An abstract destroyable class with static destroy and isDestroyable methods\n */\nexport function Destroyable<\n\tAllocated extends Record<PropertyKey, any> = Record<PropertyKey, any>,\n>(): abstract new () => (AbstractDestroyable<Allocated> & {\n\t[allocatedValues]: Allocated\n}) & {\n\tdestroy(obj: any): boolean\n\tisDestroyable(obj: any): boolean\n}\n\nexport function Destroyable<\n\tT extends new (\n\t\t...args: any[]\n\t) => any,\n\tAllocated extends Record<PropertyKey, any> = Record<PropertyKey, any>,\n>(base?: T | Destructor<Allocated>, destructorObj?: Destructor<Allocated>) {\n\tif (base && typeof base !== 'function') {\n\t\tdestructorObj = base as Destructor<Allocated>\n\t\tbase = undefined\n\t}\n\tif (!base) {\n\t\tbase = class {} as T\n\t}\n\n\treturn class Destroyable extends (base as T) {\n\t\tstatic readonly destructors = new WeakMap<any, () => void>()\n\t\tstatic destroy(obj: Destroyable) {\n\t\t\tconst destructor = Destroyable.destructors.get(obj)\n\t\t\tif (!destructor) return false\n\t\t\tfr.unregister(obj)\n\t\t\tDestroyable.destructors.delete(obj)\n\t\t\tObject.setPrototypeOf(obj, new Proxy({}, destroyedHandler))\n\t\t\t// Clear all own properties\n\t\t\tfor (const key of Object.getOwnPropertyNames(obj)) {\n\t\t\t\tdelete (obj as any)[key]\n\t\t\t}\n\t\t\tdestructor()\n\t\t\treturn true\n\t\t}\n\t\tstatic isDestroyable(obj: Destroyable) {\n\t\t\treturn Destroyable.destructors.has(obj)\n\t\t}\n\n\t\tdeclare [forwardProperties]: PropertyKey[]\n\t\treadonly [allocatedValues]: Allocated\n\t\tconstructor(...args: any[]) {\n\t\t\tsuper(...args)\n\t\t\tconst allocated = {} as Allocated\n\t\t\tthis[allocatedValues] = allocated\n\t\t\t// @ts-expect-error `this` is an AbstractDestroyable\n\t\t\tconst myDestructor = destructorObj?.destructor ?? this[destructor]\n\t\t\tif (!myDestructor) {\n\t\t\t\tthrow new DestructionError('Destructor is not defined')\n\t\t\t}\n\t\t\tfunction destruction() {\n\t\t\t\tmyDestructor(allocated)\n\t\t\t}\n\t\t\tDestroyable.destructors.set(this, destruction)\n\t\t\tfr.register(this, destruction, this)\n\t\t}\n\t}\n}\n\nconst forwardProperties = Symbol('forwardProperties')\n/**\n * Decorator that marks properties to be stored in the allocated object and passed to the destructor\n * Use with accessor properties or explicit get/set pairs\n */\nexport const allocated = decorator({\n\tsetter(original, propertyKey) {\n\t\treturn function (value) {\n\t\t\tthis[allocatedValues][propertyKey] = value\n\t\t\treturn original.call(this, value)\n\t\t}\n\t},\n})\n\n/**\n * Registers a callback to be called when an object is garbage collected\n * @param cb - The callback function to execute on garbage collection\n * @returns The object whose reference can be collected\n */\nexport function callOnGC(cb: () => void) {\n\tlet called = false\n\tconst forward = () => {\n\t\tif (called) return\n\t\tcalled = true\n\t\tcb()\n\t}\n\tfr.register(forward, cb, cb)\n\treturn forward\n}\n\n/**\n * Context Manager Protocol for `using` statement integration\n * Provides automatic resource cleanup when used with the `using` statement\n */\nexport interface ContextManager<T = any> {\n\t[Symbol.dispose](): void\n\tvalue?: T\n}\n"],"names":["decorator"],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <title>Mutts Reactivity DevTools</title>
6
+ <script src="devtools.js" defer></script>
7
+ </head>
8
+ <body></body>
9
+ </html>
@@ -0,0 +1,5 @@
1
+ // Small bootstrap script that registers the custom DevTools panel.
2
+ // The global `chrome` object is provided by the DevTools environment.
3
+ // @ts-ignore
4
+ chrome.devtools.panels.create('Mutts Reactivity', '', 'panel.html', function () { });
5
+ //# sourceMappingURL=devtools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"devtools.js","sources":["../../devtool/devtools.ts"],"sourcesContent":["// Small bootstrap script that registers the custom DevTools panel.\n// The global `chrome` object is provided by the DevTools environment.\n\n// @ts-ignore\nchrome.devtools.panels.create('Mutts Reactivity', '', 'panel.html', function () {})\n\n\n"],"names":[],"mappings":"AAAA;AACA;AAEA;AACA,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,kBAAkB,EAAE,EAAE,EAAE,YAAY,EAAE,YAAA,EAAa,CAAC,CAAC"}
@@ -0,0 +1,8 @@
1
+ {
2
+ "manifest_version": 3,
3
+ "name": "Mutts Reactivity DevTools",
4
+ "description": "Quick demo panel that draws the Mutts reactivity graph with Cytoscape.",
5
+ "version": "0.1.0",
6
+ "devtools_page": "devtools.html",
7
+ "permissions": []
8
+ }
@@ -0,0 +1,72 @@
1
+ :root {
2
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
3
+ color: #f4f4f4;
4
+ background-color: #0d1117;
5
+ }
6
+
7
+ html,
8
+ body {
9
+ margin: 0;
10
+ padding: 0;
11
+ height: 100%;
12
+ background-color: #0d1117;
13
+ color: #f4f4f4;
14
+ }
15
+
16
+ body {
17
+ display: flex;
18
+ flex-direction: column;
19
+ }
20
+
21
+ .toolbar {
22
+ display: flex;
23
+ align-items: center;
24
+ gap: 1rem;
25
+ padding: 0.5rem 1rem;
26
+ border-bottom: 1px solid #30363d;
27
+ background: #161b22;
28
+ font-size: 0.9rem;
29
+ }
30
+
31
+ .toolbar label {
32
+ display: flex;
33
+ flex-direction: column;
34
+ font-size: 0.75rem;
35
+ gap: 0.2rem;
36
+ }
37
+
38
+ .toolbar input,
39
+ .toolbar select,
40
+ .toolbar button {
41
+ font: inherit;
42
+ padding: 0.3rem 0.5rem;
43
+ border-radius: 4px;
44
+ border: 1px solid #30363d;
45
+ background: #0d1117;
46
+ color: inherit;
47
+ }
48
+
49
+ .toolbar button {
50
+ cursor: pointer;
51
+ background: #238636;
52
+ border-color: #2ea043;
53
+ color: white;
54
+ }
55
+
56
+ .toolbar #status {
57
+ margin-left: auto;
58
+ font-size: 0.75rem;
59
+ opacity: 0.85;
60
+ }
61
+
62
+ #graph {
63
+ flex: 1;
64
+ position: relative;
65
+ background: #010409;
66
+ }
67
+
68
+ .vis-network {
69
+ width: 100% !important;
70
+ height: 100% !important;
71
+ background: transparent;
72
+ }
@@ -0,0 +1,31 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <title>Mutts Reactivity Graph</title>
6
+ <link rel="stylesheet" href="panel.css" />
7
+ </head>
8
+ <body>
9
+ <header class="toolbar">
10
+ <button id="refresh">Refresh from page</button>
11
+ <label>
12
+ Layout
13
+ <select id="layout">
14
+ <option value="hierarchical">Tree</option>
15
+ <option value="physics">Force</option>
16
+ </select>
17
+ </label>
18
+ <label>
19
+ Hide isolated
20
+ <input id="hideIsolated" type="checkbox" checked />
21
+ </label>
22
+ <label>
23
+ Search
24
+ <input id="search" type="search" placeholder="effect id or label" />
25
+ </label>
26
+ <span id="status"></span>
27
+ </header>
28
+ <main id="graph"></main>
29
+ <script type="module" src="panel.js"></script>
30
+ </body>
31
+ </html>