proxy-vir 0.0.2 → 2.0.0

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/LICENSE-MIT CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2023 electrovir
3
+ Copyright (c) 2024 electrovir
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -0,0 +1,108 @@
1
+ import { type AnyFunction, type AnyObject, type PartialWithUndefined } from '@augment-vir/common';
2
+ import { type RequireExactlyOne } from 'type-fest';
3
+ /**
4
+ * Options for creating a new proxy wrapper.
5
+ *
6
+ * @category Internal
7
+ */
8
+ export type CreateProxyOptions<ProxyType> = {
9
+ /**
10
+ * Indicates if this proxy is meant to be callable, or, in other words, if this proxy is meant
11
+ * to proxy a function rather than just an object.
12
+ */
13
+ isCallable: boolean;
14
+ /**
15
+ * Indicates if the proxy should not be extensible. By default they are extensible, so set this
16
+ * to true to change that behavior. Read JavaScript docs for "Object.isExtensible()" to
17
+ * understand what being extensible means:
18
+ * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible
19
+ */
20
+ isNotExtensible: boolean;
21
+ } & RequireExactlyOne<{
22
+ /** Initial Target to wrap */
23
+ initialTarget: Partial<ProxyType>;
24
+ /** Initial Targets to wrap, in priority order */
25
+ initialTargets: ReadonlyArray<Partial<ProxyType>>;
26
+ }>;
27
+ /**
28
+ * Base type for a proxy target.
29
+ *
30
+ * @category Internal
31
+ */
32
+ export type ProxyTypeBase = AnyObject | AnyFunction;
33
+ /**
34
+ * An interface for modifying a proxy after the fact.
35
+ *
36
+ * @category Main
37
+ */
38
+ export type MultiTargetProxyModifier<ProxyType extends ProxyTypeBase> = {
39
+ /**
40
+ * Add a target to the internal list of prioritized targets. Since this will be a fallback
41
+ * target, a property from this target will only be used if no previously added target already
42
+ * has the property.
43
+ */
44
+ addFallbackTarget(target: Partial<ProxyType>): void;
45
+ /**
46
+ * Add a target to the internal list of prioritized targets. Since this will be an override
47
+ * target, a property from this target will always be used unless a new override target with the
48
+ * same property is added or if the properties are modified on the proxy itself.
49
+ */
50
+ addOverrideTarget(target: Partial<ProxyType>): void;
51
+ /** Remove the given target from the internal list of prioritized targets. */
52
+ removeTarget(target: Partial<ProxyType>): boolean;
53
+ /**
54
+ * Get a list of all internal targets, in priority order. This is mostly only useful for
55
+ * debugging purposes.
56
+ */
57
+ getAllTargets(): ReadonlyArray<Partial<ProxyType>>;
58
+ /**
59
+ * Add a new proxy handler. Since this will be an override handler, a method from this handler
60
+ * will always be used unless a new override handler with the same method is added or if the
61
+ * methods are modified on the handler object itself.
62
+ */
63
+ addProxyHandlerOverride(handlerOverride: ProxyHandler<ProxyType>): void;
64
+ /**
65
+ * Add a new proxy handler. Since this will be a fallback handler, a method from this handler
66
+ * will only be used if no previously added override already has the method.
67
+ */
68
+ addProxyHandlerFallback(handlerOverride: ProxyHandler<ProxyType>): void;
69
+ /** Remove the given proxy handler override from the internal list of proxy handler overrides. */
70
+ removeProxyOverride(handlerOverride: ProxyHandler<ProxyType>): boolean;
71
+ };
72
+ /**
73
+ * A proxy wrapper which allows performing multiple operations on the proxy to modify it after the
74
+ * fact (with `.proxyModifier`), such as merging multiple proxies together or adding new proxy
75
+ * handler methods.
76
+ *
77
+ * @category Main
78
+ */
79
+ export type WrappedMultiTargetProxy<ProxyType extends ProxyTypeBase> = {
80
+ proxy: ProxyType;
81
+ proxyModifier: MultiTargetProxyModifier<ProxyType>;
82
+ };
83
+ /**
84
+ * Create an instance of {@link WrappedMultiTargetProxy} which can be used to merge multiple targets
85
+ * together or override proxy handler methods.
86
+ *
87
+ * @category Main
88
+ * @example
89
+ *
90
+ * ```ts
91
+ * import {createWrappedMultiTargetProxy} from 'proxy-vir';
92
+ *
93
+ * // something you imported from a 3rd party library that you want to wrap
94
+ * const importedThing = {
95
+ * doThingA() {},
96
+ * };
97
+ *
98
+ * const thingWrapper = createWrappedMultiTargetProxy({
99
+ * initialTarget: importedThing,
100
+ * });
101
+ *
102
+ * // add a new override
103
+ * thingWrapper.proxyModifier.addOverrideTarget({
104
+ * doThingA() {},
105
+ * });
106
+ * ```
107
+ */
108
+ export declare function createWrappedMultiTargetProxy<ProxyType extends ProxyTypeBase>(options?: PartialWithUndefined<CreateProxyOptions<ProxyType>> | undefined): WrappedMultiTargetProxy<ProxyType>;
@@ -1,5 +1,31 @@
1
- import { getObjectTypedKeys, typedHasProperty } from '@augment-vir/common';
2
- import { createPrioritizedProperties } from '../prioritized-properties';
1
+ import { check } from '@augment-vir/assert';
2
+ import { getObjectTypedKeys, } from '@augment-vir/common';
3
+ import { createPrioritizedProperties } from './prioritized-properties.js';
4
+ /**
5
+ * Create an instance of {@link WrappedMultiTargetProxy} which can be used to merge multiple targets
6
+ * together or override proxy handler methods.
7
+ *
8
+ * @category Main
9
+ * @example
10
+ *
11
+ * ```ts
12
+ * import {createWrappedMultiTargetProxy} from 'proxy-vir';
13
+ *
14
+ * // something you imported from a 3rd party library that you want to wrap
15
+ * const importedThing = {
16
+ * doThingA() {},
17
+ * };
18
+ *
19
+ * const thingWrapper = createWrappedMultiTargetProxy({
20
+ * initialTarget: importedThing,
21
+ * });
22
+ *
23
+ * // add a new override
24
+ * thingWrapper.proxyModifier.addOverrideTarget({
25
+ * doThingA() {},
26
+ * });
27
+ * ```
28
+ */
3
29
  export function createWrappedMultiTargetProxy(options) {
4
30
  /** This target will always be used first. */
5
31
  const primaryTarget = options?.isCallable ? () => { } : {};
@@ -25,6 +51,7 @@ export function createWrappedMultiTargetProxy(options) {
25
51
  ? {
26
52
  apply() {
27
53
  if (proxyOverrides.combinedProperties.apply) {
54
+ // eslint-disable-next-line @typescript-eslint/unbound-method
28
55
  return proxyOverrides.combinedProperties.apply;
29
56
  }
30
57
  const firstCallableTarget = targetProperties
@@ -89,7 +116,7 @@ export function createWrappedMultiTargetProxy(options) {
89
116
  if (deletedProperties.has(property)) {
90
117
  return false;
91
118
  }
92
- return typedHasProperty(combinedTargets, property);
119
+ return check.hasKey(combinedTargets, property);
93
120
  },
94
121
  isExtensible(combinedTargets) {
95
122
  if (proxyOverrides.combinedProperties.isExtensible) {
@@ -140,23 +167,12 @@ export function createWrappedMultiTargetProxy(options) {
140
167
  },
141
168
  });
142
169
  const proxyModifier = {
143
- /**
144
- * Add a target to the internal list of prioritized targets. Since this will be a fallback
145
- * target, a property from this target will only be used if no previously added target
146
- * already has the property.
147
- */
148
170
  addFallbackTarget(target) {
149
171
  targetProperties.addFallback(target);
150
172
  },
151
- /**
152
- * Add a target to the internal list of prioritized targets. Since this will be an override
153
- * target, a property from this target will always be used unless a new override target with
154
- * the same property is added or if the properties are modified on the proxy itself.
155
- */
156
173
  addOverrideTarget(target) {
157
174
  targetProperties.addOverride(target);
158
175
  },
159
- /** Remove the given target from the internal list of prioritized targets. */
160
176
  removeTarget(target) {
161
177
  return targetProperties.removeEntry(target);
162
178
  },
@@ -169,10 +185,6 @@ export function createWrappedMultiTargetProxy(options) {
169
185
  removeProxyOverride(handlerOverride) {
170
186
  return proxyOverrides.removeEntry(handlerOverride);
171
187
  },
172
- /**
173
- * The list of internal prioritized targets, in priority order. This is mostly only useful
174
- * for debugging purposes.
175
- */
176
188
  getAllTargets() {
177
189
  return targetProperties.getCurrentList();
178
190
  },
@@ -0,0 +1 @@
1
+ export * from './create-multi-target-proxy.js';
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export * from './create-multi-target-proxy.js';
@@ -1,24 +1,24 @@
1
- import { PartialAndUndefined } from '@augment-vir/common';
1
+ import { type PartialWithUndefined } from '@augment-vir/common';
2
2
  export type PriorityListInputs<EntryType> = {
3
3
  initialList: ReadonlyArray<EntryType>;
4
4
  overrideEntryPoint: number;
5
5
  updateCallback?: (combined: EntryType) => void;
6
6
  };
7
7
  /**
8
- * Stores and allows updating of a list of entries from which a single object created. Properties
8
+ * Stores and allows updating of a list of entries from which a single object is created. Properties
9
9
  * for the single object are chosen from the entries by the entry order in the list.
10
10
  */
11
- export declare function createPrioritizedProperties<EntryType>(options?: PartialAndUndefined<PriorityListInputs<EntryType>>): {
11
+ export declare function createPrioritizedProperties<EntryType>(options?: PartialWithUndefined<PriorityListInputs<EntryType>>): {
12
12
  /**
13
13
  * An object containing all properties combined from the current priority list of entries.
14
14
  * This reference never changes, just its contents, so you are safe to grab and use this
15
15
  * object directly.
16
16
  */
17
17
  combinedProperties: EntryType;
18
- addOverride(entry: EntryType): void;
19
- addFallback(entry: EntryType): void;
18
+ addOverride(entry: Partial<EntryType>): void;
19
+ addFallback(entry: Partial<EntryType>): void;
20
20
  /** Return value indicates if the given entry was removed or not. */
21
- removeEntry(entry: EntryType): boolean;
21
+ removeEntry(entry: Partial<EntryType>): boolean;
22
22
  forceUpdate(): void;
23
- getCurrentList(): ReadonlyArray<EntryType>;
23
+ getCurrentList(): ReadonlyArray<Partial<EntryType>>;
24
24
  };
@@ -1,21 +1,20 @@
1
- import { getObjectTypedKeys, typedHasProperty, } from '@augment-vir/common';
1
+ import { check } from '@augment-vir/assert';
2
+ import { getObjectTypedKeys } from '@augment-vir/common';
2
3
  function listToMapInit(options) {
3
4
  if (options?.initialList) {
4
- return options.initialList
5
- .map((initialEntry) => {
5
+ return options.initialList.flatMap((initialEntry) => {
6
6
  return getObjectTypedKeys(initialEntry).map((key) => {
7
7
  return [
8
8
  key,
9
9
  initialEntry[key],
10
10
  ];
11
11
  });
12
- })
13
- .flat();
12
+ });
14
13
  }
15
14
  return [];
16
15
  }
17
16
  /**
18
- * Stores and allows updating of a list of entries from which a single object created. Properties
17
+ * Stores and allows updating of a list of entries from which a single object is created. Properties
19
18
  * for the single object are chosen from the entries by the entry order in the list.
20
19
  */
21
20
  export function createPrioritizedProperties(options) {
@@ -29,7 +28,7 @@ export function createPrioritizedProperties(options) {
29
28
  list.forEach((entry) => {
30
29
  getObjectTypedKeys(entry).forEach((property) => {
31
30
  // only save the property if it hasn't been saved already
32
- if (!typedHasProperty(combinedProperties, property)) {
31
+ if (!check.hasKey(combinedProperties, property)) {
33
32
  combinedProperties[property] = entry[property];
34
33
  }
35
34
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "proxy-vir",
3
- "version": "0.0.2",
3
+ "version": "2.0.0",
4
4
  "description": "An easier Proxy.",
5
5
  "keywords": [
6
6
  "proxy",
@@ -14,63 +14,78 @@
14
14
  },
15
15
  "repository": {
16
16
  "type": "git",
17
- "url": "https://github.com/electrovir/proxy-vir"
17
+ "url": "git+https://github.com/electrovir/proxy-vir.git"
18
18
  },
19
19
  "license": "(MIT or CC0 1.0)",
20
20
  "author": {
21
21
  "name": "electrovir",
22
22
  "url": "https://github.com/electrovir"
23
23
  },
24
- "main": "dist/cjs/index.js",
25
- "module": "dist/esm/index.js",
26
- "types": "dist/types/index.d.ts",
24
+ "type": "module",
25
+ "main": "dist/index.js",
26
+ "module": "dist/index.js",
27
+ "types": "dist/index.d.ts",
27
28
  "scripts": {
28
- "compile": "rm -rf dist && tsc --project tsconfig.json && tsc --project tsconfig.cjs.json",
29
- "docs": "virmator docs README.md --index src/index.ts",
29
+ "compile": "virmator compile",
30
+ "docs": "virmator docs",
30
31
  "format": "virmator format",
31
- "publish": "virmator publish \"npm run compile && npm run test:all\"",
32
- "start": "npm install && virmator frontend",
33
- "test": "virmator test-web",
34
- "test:all": "concurrently --kill-others-on-fail --kill-signal SIGKILL -c auto --colors --names types,tests,spelling,format,docs,deps \"npm run test:types\" \"npm run test:coverage\" \"npm run test:spelling\" \"npm run test:format\" \"npm run test:docs\" \"npm run test:deps\"",
35
- "test:coverage": "npm run test coverage",
32
+ "lint": "virmator lint fix",
33
+ "publish": "virmator publish npm run test:all",
34
+ "start": "virmator frontend",
35
+ "test": "virmator test web",
36
+ "test:all": "npm run compile && concurrently --colors --kill-others-on-fail -c auto --names tests,spelling,format,docs,deps,lint \"npm run test\" \"npm run test:spelling\" \"npm run test:format\" \"npm run test:docs\" \"npm run test:deps\" \"npm run test:lint\"",
36
37
  "test:deps": "virmator deps check",
37
- "test:docs": "virmator docs check README.md --index src/index.ts",
38
+ "test:docs": "virmator docs check",
38
39
  "test:format": "virmator format check",
39
- "test:spelling": "virmator spellcheck",
40
- "test:types": "tsc --noEmit"
40
+ "test:lint": "virmator lint",
41
+ "test:spelling": "virmator spellcheck"
41
42
  },
42
43
  "dependencies": {
43
- "@augment-vir/common": "^22.0.0"
44
+ "@augment-vir/assert": "^30.7.0",
45
+ "@augment-vir/common": "^30.7.0"
44
46
  },
45
47
  "devDependencies": {
46
- "@augment-vir/browser-testing": "^22.0.0",
47
- "@augment-vir/node-js": "^22.0.0",
48
- "@open-wc/testing": "^4.0.0",
49
- "@types/mocha": "^10.0.4",
50
- "@web/dev-server-esbuild": "^1.0.1",
51
- "@web/test-runner": "^0.18.0",
48
+ "@augment-vir/test": "^30.7.0",
49
+ "@eslint/eslintrc": "^3.1.0",
50
+ "@eslint/js": "^9.14.0",
51
+ "@stylistic/eslint-plugin": "^2.10.1",
52
+ "@stylistic/eslint-plugin-ts": "^2.10.1",
53
+ "@typescript-eslint/eslint-plugin": "^8.14.0",
54
+ "@web/dev-server-esbuild": "^1.0.3",
55
+ "@web/test-runner": "^0.19.0",
52
56
  "@web/test-runner-commands": "^0.9.0",
53
57
  "@web/test-runner-playwright": "^0.11.0",
54
- "@web/test-runner-visual-regression": "^0.9.0",
55
- "cspell": "^8.0.0",
56
- "dependency-cruiser": "^15.3.0",
57
- "esbuild": "^0.19.6",
58
- "istanbul-smart-text-reporter": "^1.1.3",
59
- "markdown-code-example-inserter": "^0.3.3",
60
- "npm-check-updates": "~16.12.3",
61
- "prettier": "^3.1.0",
62
- "prettier-plugin-interpolated-html-tags": "^1.0.2",
63
- "prettier-plugin-jsdoc": "^1.1.1",
64
- "prettier-plugin-multiline-arrays": "^3.0.0",
65
- "prettier-plugin-organize-imports": "^3.2.4",
66
- "prettier-plugin-packagejson": "^2.4.6",
67
- "prettier-plugin-sort-json": "^3.1.0",
68
- "prettier-plugin-toml": "^1.0.0",
69
- "run-time-assertions": "^0.2.1",
70
- "type-fest": "^4.8.1",
71
- "typedoc": "^0.25.3",
72
- "virmator": "^11.1.2",
73
- "vite": "^5.0.0",
74
- "vite-tsconfig-paths": "^4.2.1"
58
+ "@web/test-runner-visual-regression": "^0.10.0",
59
+ "cspell": "^8.16.0",
60
+ "dependency-cruiser": "^16.6.0",
61
+ "esbuild": "^0.24.0",
62
+ "eslint": "^9.14.0",
63
+ "eslint-config-prettier": "^9.1.0",
64
+ "eslint-plugin-jsdoc": "^50.5.0",
65
+ "eslint-plugin-monorepo-cop": "^1.0.2",
66
+ "eslint-plugin-playwright": "^2.0.1",
67
+ "eslint-plugin-prettier": "^5.2.1",
68
+ "eslint-plugin-require-extensions": "^0.1.3",
69
+ "eslint-plugin-sonarjs": "^2.0.4",
70
+ "eslint-plugin-unicorn": "^56.0.0",
71
+ "istanbul-smart-text-reporter": "^1.1.5",
72
+ "markdown-code-example-inserter": "^3.0.1",
73
+ "npm-check-updates": "^17.1.11",
74
+ "prettier": "^3.3.3",
75
+ "prettier-plugin-interpolated-html-tags": "^1.0.5",
76
+ "prettier-plugin-jsdoc": "^1.3.0",
77
+ "prettier-plugin-multiline-arrays": "^3.0.6",
78
+ "prettier-plugin-organize-imports": "^4.1.0",
79
+ "prettier-plugin-packagejson": "^2.5.3",
80
+ "prettier-plugin-sort-json": "^4.0.0",
81
+ "prettier-plugin-toml": "^2.0.1",
82
+ "type-fest": "^4.27.0",
83
+ "typedoc": "^0.26.11",
84
+ "typescript": "^5.6.3",
85
+ "typescript-eslint": "^8.14.0",
86
+ "virmator": "^13.8.1"
87
+ },
88
+ "engines": {
89
+ "node": ">=22"
75
90
  }
76
91
  }
package/dist/cjs/index.js DELETED
@@ -1,17 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./proxy-vir/create-multi-target-proxy"), exports);
@@ -1,75 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createPrioritizedProperties = void 0;
4
- const common_1 = require("@augment-vir/common");
5
- function listToMapInit(options) {
6
- if (options?.initialList) {
7
- return options.initialList
8
- .map((initialEntry) => {
9
- return (0, common_1.getObjectTypedKeys)(initialEntry).map((key) => {
10
- return [
11
- key,
12
- initialEntry[key],
13
- ];
14
- });
15
- })
16
- .flat();
17
- }
18
- return [];
19
- }
20
- /**
21
- * Stores and allows updating of a list of entries from which a single object created. Properties
22
- * for the single object are chosen from the entries by the entry order in the list.
23
- */
24
- function createPrioritizedProperties(options) {
25
- const list = [...(options?.initialList ?? [])];
26
- const combinedProperties = Object.fromEntries(listToMapInit(options));
27
- function updateObject() {
28
- // clear out all the object's current keys
29
- (0, common_1.getObjectTypedKeys)(combinedProperties).forEach((property) => {
30
- delete combinedProperties[property];
31
- });
32
- list.forEach((entry) => {
33
- (0, common_1.getObjectTypedKeys)(entry).forEach((property) => {
34
- // only save the property if it hasn't been saved already
35
- if (!(0, common_1.typedHasProperty)(combinedProperties, property)) {
36
- combinedProperties[property] = entry[property];
37
- }
38
- });
39
- });
40
- options?.updateCallback?.(combinedProperties);
41
- }
42
- return {
43
- /**
44
- * An object containing all properties combined from the current priority list of entries.
45
- * This reference never changes, just its contents, so you are safe to grab and use this
46
- * object directly.
47
- */
48
- combinedProperties,
49
- addOverride(entry) {
50
- list.splice(options?.overrideEntryPoint ?? 0, 0, entry);
51
- updateObject();
52
- },
53
- addFallback(entry) {
54
- list.push(entry);
55
- updateObject();
56
- },
57
- /** Return value indicates if the given entry was removed or not. */
58
- removeEntry(entry) {
59
- const entryIndex = list.indexOf(entry);
60
- if (entryIndex === -1) {
61
- return false;
62
- }
63
- list.splice(entryIndex, 1);
64
- updateObject();
65
- return true;
66
- },
67
- forceUpdate() {
68
- updateObject();
69
- },
70
- getCurrentList() {
71
- return [...list];
72
- },
73
- };
74
- }
75
- exports.createPrioritizedProperties = createPrioritizedProperties;
@@ -1,196 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createWrappedMultiTargetProxy = void 0;
4
- const common_1 = require("@augment-vir/common");
5
- const prioritized_properties_1 = require("../prioritized-properties");
6
- function createWrappedMultiTargetProxy(options) {
7
- /** This target will always be used first. */
8
- const primaryTarget = options?.isCallable ? () => { } : {};
9
- const deletedProperties = new Set();
10
- let prototype = Object.getPrototypeOf(primaryTarget);
11
- let isExtensible = !options?.isNotExtensible;
12
- const proxyOverrides = (0, prioritized_properties_1.createPrioritizedProperties)();
13
- const targetProperties = (0, prioritized_properties_1.createPrioritizedProperties)({
14
- initialList: [primaryTarget],
15
- /** This is set to 1 so that the primaryTarget above is never overridden. */
16
- overrideEntryPoint: 1,
17
- updateCallback(combinedObject) {
18
- Object.setPrototypeOf(combinedObject, prototype);
19
- deletedProperties.forEach((property) => {
20
- delete combinedObject[property];
21
- });
22
- if (!isExtensible && Object.isExtensible(combinedObject)) {
23
- Object.preventExtensions(combinedObject);
24
- }
25
- },
26
- });
27
- const functionHandlers = options?.isCallable
28
- ? {
29
- apply() {
30
- if (proxyOverrides.combinedProperties.apply) {
31
- return proxyOverrides.combinedProperties.apply;
32
- }
33
- const firstCallableTarget = targetProperties
34
- .getCurrentList()
35
- .find((target) => typeof target === 'function') ?? primaryTarget;
36
- return firstCallableTarget();
37
- },
38
- }
39
- : {};
40
- const createdProxy = new Proxy(targetProperties.combinedProperties, {
41
- ...functionHandlers,
42
- defineProperty(combinedTargets, property, attributes) {
43
- if (proxyOverrides.combinedProperties.defineProperty) {
44
- return proxyOverrides.combinedProperties.defineProperty(combinedTargets, property, attributes);
45
- }
46
- if (!isExtensible) {
47
- return false;
48
- }
49
- deletedProperties.delete(property);
50
- Object.defineProperty(primaryTarget, property, attributes);
51
- targetProperties.forceUpdate();
52
- return true;
53
- },
54
- deleteProperty(combinedTargets, property) {
55
- if (proxyOverrides.combinedProperties.deleteProperty) {
56
- return proxyOverrides.combinedProperties.deleteProperty(combinedTargets, property);
57
- }
58
- if (!isExtensible) {
59
- return false;
60
- }
61
- deletedProperties.add(property);
62
- return true;
63
- },
64
- get(combinedTargets, property, receiver) {
65
- if (proxyOverrides.combinedProperties.get) {
66
- return proxyOverrides.combinedProperties.get(combinedTargets, property, receiver);
67
- }
68
- if (deletedProperties.has(property)) {
69
- return undefined;
70
- }
71
- return combinedTargets[property];
72
- },
73
- getOwnPropertyDescriptor(combinedTargets, property) {
74
- if (proxyOverrides.combinedProperties.getOwnPropertyDescriptor) {
75
- return proxyOverrides.combinedProperties.getOwnPropertyDescriptor(combinedTargets, property);
76
- }
77
- if (deletedProperties.has(property)) {
78
- return undefined;
79
- }
80
- return Object.getOwnPropertyDescriptor(combinedTargets, property);
81
- },
82
- getPrototypeOf(combinedTargets) {
83
- if (proxyOverrides.combinedProperties.getPrototypeOf) {
84
- return proxyOverrides.combinedProperties.getPrototypeOf(combinedTargets);
85
- }
86
- return Object.getPrototypeOf(combinedTargets);
87
- },
88
- has(combinedTargets, property) {
89
- if (proxyOverrides.combinedProperties.has) {
90
- return proxyOverrides.combinedProperties.has(combinedTargets, property);
91
- }
92
- if (deletedProperties.has(property)) {
93
- return false;
94
- }
95
- return (0, common_1.typedHasProperty)(combinedTargets, property);
96
- },
97
- isExtensible(combinedTargets) {
98
- if (proxyOverrides.combinedProperties.isExtensible) {
99
- return proxyOverrides.combinedProperties.isExtensible(combinedTargets);
100
- }
101
- return isExtensible;
102
- },
103
- ownKeys(combinedTargets) {
104
- if (proxyOverrides.combinedProperties.ownKeys) {
105
- return proxyOverrides.combinedProperties.ownKeys(combinedTargets);
106
- }
107
- return Array.from((0, common_1.getObjectTypedKeys)(combinedTargets))
108
- .map((key) => {
109
- return typeof key === 'number' ? String(key) : key;
110
- })
111
- .filter((property) => !deletedProperties.has(property));
112
- },
113
- preventExtensions(combinedTargets) {
114
- if (proxyOverrides.combinedProperties.preventExtensions) {
115
- return proxyOverrides.combinedProperties.preventExtensions(combinedTargets);
116
- }
117
- isExtensible = false;
118
- targetProperties.forceUpdate();
119
- return true;
120
- },
121
- set(combinedTargets, property, newValue, receiver) {
122
- if (proxyOverrides.combinedProperties.set) {
123
- return proxyOverrides.combinedProperties.set(combinedTargets, property, newValue, receiver);
124
- }
125
- if (!isExtensible) {
126
- return false;
127
- }
128
- deletedProperties.delete(property);
129
- primaryTarget[property] = newValue;
130
- targetProperties.forceUpdate();
131
- return true;
132
- },
133
- setPrototypeOf(combinedTargets, newPrototype) {
134
- if (proxyOverrides.combinedProperties.setPrototypeOf) {
135
- return proxyOverrides.combinedProperties.setPrototypeOf(combinedTargets, newPrototype);
136
- }
137
- if (!isExtensible) {
138
- return false;
139
- }
140
- prototype = newPrototype;
141
- targetProperties.forceUpdate();
142
- return true;
143
- },
144
- });
145
- const proxyModifier = {
146
- /**
147
- * Add a target to the internal list of prioritized targets. Since this will be a fallback
148
- * target, a property from this target will only be used if no previously added target
149
- * already has the property.
150
- */
151
- addFallbackTarget(target) {
152
- targetProperties.addFallback(target);
153
- },
154
- /**
155
- * Add a target to the internal list of prioritized targets. Since this will be an override
156
- * target, a property from this target will always be used unless a new override target with
157
- * the same property is added or if the properties are modified on the proxy itself.
158
- */
159
- addOverrideTarget(target) {
160
- targetProperties.addOverride(target);
161
- },
162
- /** Remove the given target from the internal list of prioritized targets. */
163
- removeTarget(target) {
164
- return targetProperties.removeEntry(target);
165
- },
166
- addProxyHandlerOverride(handlerOverride) {
167
- proxyOverrides.addOverride(handlerOverride);
168
- },
169
- addProxyHandlerFallback(handlerOverride) {
170
- proxyOverrides.addFallback(handlerOverride);
171
- },
172
- removeProxyOverride(handlerOverride) {
173
- return proxyOverrides.removeEntry(handlerOverride);
174
- },
175
- /**
176
- * The list of internal prioritized targets, in priority order. This is mostly only useful
177
- * for debugging purposes.
178
- */
179
- getAllTargets() {
180
- return targetProperties.getCurrentList();
181
- },
182
- };
183
- if (options && 'initialTarget' in options && options.initialTarget) {
184
- proxyModifier.addFallbackTarget(options.initialTarget);
185
- }
186
- else if (options && 'initialTargets' in options && options.initialTargets) {
187
- options.initialTargets.forEach((initialTarget) => {
188
- proxyModifier.addOverrideTarget(initialTarget);
189
- });
190
- }
191
- return {
192
- proxy: createdProxy,
193
- proxyModifier,
194
- };
195
- }
196
- exports.createWrappedMultiTargetProxy = createWrappedMultiTargetProxy;
package/dist/esm/index.js DELETED
@@ -1 +0,0 @@
1
- export * from './proxy-vir/create-multi-target-proxy';
@@ -1 +0,0 @@
1
- export * from './proxy-vir/create-multi-target-proxy';
@@ -1,37 +0,0 @@
1
- import { PartialAndUndefined } from '@augment-vir/common';
2
- import { RequireExactlyOne } from 'type-fest';
3
- export type CreateProxyOptions<ProxyType> = {
4
- /**
5
- * Indicates if this proxy is meant to be callable, or, in other words, if this proxy is meant
6
- * to proxy a function rather than just an object.
7
- */
8
- isCallable: boolean;
9
- /**
10
- * Indicates if the proxy should not be extensible. By default they are extensible, so set this
11
- * to true to change that behavior. Read JavaScript docs for "Object.isExtensible()" to
12
- * understand what being extensible means:
13
- * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible
14
- */
15
- isNotExtensible: boolean;
16
- } & RequireExactlyOne<{
17
- /** Initial Target to wrap */
18
- initialTarget: Partial<ProxyType>;
19
- /** Initial Targets to wrap, in priority order */
20
- initialTargets: ReadonlyArray<Partial<ProxyType>>;
21
- }>;
22
- export type ProxyTypeBase = object | Function;
23
- export type MultiTargetProxyModifier<ProxyType extends ProxyTypeBase> = {
24
- addFallbackTarget(target: Partial<ProxyType>): void;
25
- addOverrideTarget(target: Partial<ProxyType>): void;
26
- removeTarget(target: Partial<ProxyType>): boolean;
27
- getAllTargets(): ReadonlyArray<unknown>;
28
- addProxyHandlerOverride(handlerOverride: ProxyHandler<ProxyType>): void;
29
- addProxyHandlerFallback(handlerOverride: ProxyHandler<ProxyType>): void;
30
- removeProxyOverride(handlerOverride: ProxyHandler<ProxyType>): boolean;
31
- getAllTargets(): ReadonlyArray<ProxyType>;
32
- };
33
- export type WrappedMultiTargetProxy<ProxyType extends ProxyTypeBase> = {
34
- proxy: ProxyType;
35
- proxyModifier: MultiTargetProxyModifier<ProxyType>;
36
- };
37
- export declare function createWrappedMultiTargetProxy<ProxyType extends ProxyTypeBase>(options?: PartialAndUndefined<CreateProxyOptions<ProxyType>> | undefined): WrappedMultiTargetProxy<ProxyType>;