ponder 0.17.2 → 0.17.4

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 (44) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/esm/indexing/index.js +2 -2
  3. package/dist/esm/indexing/index.js.map +1 -1
  4. package/dist/esm/indexing-store/cache.js +6 -21
  5. package/dist/esm/indexing-store/cache.js.map +1 -1
  6. package/dist/esm/indexing-store/index.js +35 -39
  7. package/dist/esm/indexing-store/index.js.map +1 -1
  8. package/dist/esm/indexing-store/utils.js +21 -1
  9. package/dist/esm/indexing-store/utils.js.map +1 -1
  10. package/dist/esm/internal/metrics.js +68 -0
  11. package/dist/esm/internal/metrics.js.map +1 -1
  12. package/dist/esm/runtime/isolated.js +1 -0
  13. package/dist/esm/runtime/isolated.js.map +1 -1
  14. package/dist/esm/runtime/multichain.js +1 -0
  15. package/dist/esm/runtime/multichain.js.map +1 -1
  16. package/dist/esm/runtime/omnichain.js +1 -0
  17. package/dist/esm/runtime/omnichain.js.map +1 -1
  18. package/dist/esm/sync-realtime/index.js +1 -1
  19. package/dist/esm/sync-realtime/index.js.map +1 -1
  20. package/dist/esm/utils/copy.js +69 -58
  21. package/dist/esm/utils/copy.js.map +1 -1
  22. package/dist/types/indexing/index.d.ts.map +1 -1
  23. package/dist/types/indexing-store/cache.d.ts.map +1 -1
  24. package/dist/types/indexing-store/index.d.ts.map +1 -1
  25. package/dist/types/indexing-store/utils.d.ts +5 -0
  26. package/dist/types/indexing-store/utils.d.ts.map +1 -1
  27. package/dist/types/internal/metrics.d.ts +13 -0
  28. package/dist/types/internal/metrics.d.ts.map +1 -1
  29. package/dist/types/runtime/isolated.d.ts.map +1 -1
  30. package/dist/types/runtime/multichain.d.ts.map +1 -1
  31. package/dist/types/runtime/omnichain.d.ts.map +1 -1
  32. package/dist/types/utils/copy.d.ts +1 -1
  33. package/dist/types/utils/copy.d.ts.map +1 -1
  34. package/package.json +2 -2
  35. package/src/indexing/index.ts +4 -6
  36. package/src/indexing-store/cache.ts +20 -22
  37. package/src/indexing-store/index.ts +76 -38
  38. package/src/indexing-store/utils.ts +29 -1
  39. package/src/internal/metrics.ts +81 -0
  40. package/src/runtime/isolated.ts +1 -0
  41. package/src/runtime/multichain.ts +1 -0
  42. package/src/runtime/omnichain.ts +1 -0
  43. package/src/sync-realtime/index.ts +1 -1
  44. package/src/utils/copy.ts +76 -62
package/src/utils/copy.ts CHANGED
@@ -5,18 +5,24 @@ import util from "node:util";
5
5
  */
6
6
  export const COPY_ON_WRITE = Symbol.for("ponder:copyOnWrite");
7
7
 
8
+ const copyOnWriteCopies = new WeakMap<object, object>();
9
+
10
+ function inspectCopyOnWrite(this: object) {
11
+ return copyOnWriteCopies.get(this) ?? (this as any)[COPY_ON_WRITE] ?? this;
12
+ }
13
+
8
14
  /**
9
15
  * Create a copy-on-write proxy for an object.
10
16
  */
11
17
  export const copyOnWrite = <T extends object>(obj: T): T => {
12
18
  let copiedObject: T | undefined;
13
19
 
14
- // @ts-expect-error
15
- obj[util.inspect.custom] = () => {
16
- return copiedObject ?? obj;
17
- };
20
+ Object.defineProperty(obj, util.inspect.custom, {
21
+ value: inspectCopyOnWrite,
22
+ configurable: true,
23
+ });
18
24
 
19
- return new Proxy<T>(obj, {
25
+ const proxy = new Proxy<T>(obj, {
20
26
  get(target, prop, receiver) {
21
27
  if (prop === COPY_ON_WRITE) {
22
28
  return target;
@@ -29,6 +35,7 @@ export const copyOnWrite = <T extends object>(obj: T): T => {
29
35
  copiedObject === undefined
30
36
  ) {
31
37
  copiedObject = structuredClone(target);
38
+ copyOnWriteCopies.set(proxy, copiedObject);
32
39
  result = Reflect.get(copiedObject, prop, receiver);
33
40
  }
34
41
 
@@ -37,20 +44,23 @@ export const copyOnWrite = <T extends object>(obj: T): T => {
37
44
  set(target, prop, newValue, receiver) {
38
45
  if (copiedObject === undefined) {
39
46
  copiedObject = structuredClone(target);
47
+ copyOnWriteCopies.set(proxy, copiedObject);
40
48
  }
41
- return Reflect.set(copiedObject!, prop, newValue, receiver);
49
+ return Reflect.set(copiedObject, prop, newValue, receiver);
42
50
  },
43
51
  deleteProperty(target, prop) {
44
52
  if (copiedObject === undefined) {
45
53
  copiedObject = structuredClone(target);
54
+ copyOnWriteCopies.set(proxy, copiedObject);
46
55
  }
47
- return Reflect.deleteProperty(copiedObject!, prop);
56
+ return Reflect.deleteProperty(copiedObject, prop);
48
57
  },
49
58
  defineProperty(target, prop, descriptor) {
50
59
  if (copiedObject === undefined) {
51
60
  copiedObject = structuredClone(target);
61
+ copyOnWriteCopies.set(proxy, copiedObject);
52
62
  }
53
- return Reflect.defineProperty(copiedObject!, prop, descriptor);
63
+ return Reflect.defineProperty(copiedObject, prop, descriptor);
54
64
  },
55
65
  ownKeys(target) {
56
66
  return Reflect.ownKeys(copiedObject ?? target);
@@ -62,6 +72,8 @@ export const copyOnWrite = <T extends object>(obj: T): T => {
62
72
  return Reflect.getOwnPropertyDescriptor(copiedObject ?? target, prop);
63
73
  },
64
74
  });
75
+
76
+ return proxy;
65
77
  };
66
78
 
67
79
  /**
@@ -70,82 +82,84 @@ export const copyOnWrite = <T extends object>(obj: T): T => {
70
82
  * @dev This function supports copying objects that
71
83
  * have been created with `copyOnWrite`.
72
84
  */
73
- export const copy = <T>(obj: T): T => {
85
+ export const copy = <T>(obj: T, fast: boolean): T => {
74
86
  if (obj === null || typeof obj !== "object") {
75
87
  return obj;
76
88
  }
77
89
 
78
- const hasProxy = (obj: any): boolean => {
79
- if (obj === null || typeof obj !== "object") {
80
- return false;
81
- }
90
+ // @ts-expect-error
91
+ const proxy = obj[COPY_ON_WRITE];
92
+ if (proxy !== undefined) return proxy;
82
93
 
83
- if (obj[COPY_ON_WRITE] !== undefined) {
84
- return true;
85
- }
94
+ if (fast) {
95
+ // Note: spread operator is significantly faster than `structuredClone`
96
+ return (Array.isArray(obj) ? [...obj] : { ...obj }) as T;
97
+ }
86
98
 
87
- if (Array.isArray(obj)) {
88
- return obj.some((element) => hasProxy(element));
99
+ if (Array.isArray(obj)) {
100
+ if (hasProxy(obj)) {
101
+ // @ts-expect-error
102
+ return obj.map((element) => copy(element));
89
103
  }
90
104
 
91
- for (const value of Object.values(obj)) {
92
- if (hasProxy(value)) {
93
- return true;
94
- }
105
+ if (isDeeplyNested(obj)) return structuredClone(obj);
106
+ return [...obj] as T;
107
+ }
108
+
109
+ if (hasProxy(obj)) {
110
+ const result = {} as T;
111
+ for (const [key, value] of Object.entries(obj)) {
112
+ // @ts-expect-error
113
+ result[key] = copy(value);
95
114
  }
96
115
 
116
+ return result;
117
+ }
118
+
119
+ if (isDeeplyNested(obj)) return structuredClone(obj);
120
+ return { ...obj };
121
+ };
122
+
123
+ const hasProxy = (obj: any): boolean => {
124
+ if (obj === null || typeof obj !== "object") {
97
125
  return false;
98
- };
126
+ }
99
127
 
100
- const isDeeplyNested = (obj: any, depth = 0): boolean => {
101
- if (obj === null || typeof obj !== "object") {
102
- return false;
103
- }
128
+ if (obj[COPY_ON_WRITE] !== undefined) {
129
+ return true;
130
+ }
104
131
 
105
- if (depth > 0) {
106
- return true;
107
- }
132
+ if (Array.isArray(obj)) {
133
+ return obj.some((element) => hasProxy(element));
134
+ }
108
135
 
109
- if (Array.isArray(obj)) {
110
- return obj.some((element) => isDeeplyNested(element, depth + 1));
136
+ for (const value of Object.values(obj)) {
137
+ if (hasProxy(value)) {
138
+ return true;
111
139
  }
140
+ }
112
141
 
113
- for (const value of Object.values(obj)) {
114
- if (isDeeplyNested(value, depth + 1)) {
115
- return true;
116
- }
117
- }
142
+ return false;
143
+ };
118
144
 
145
+ const isDeeplyNested = (obj: any, depth = 0): boolean => {
146
+ if (obj === null || typeof obj !== "object") {
119
147
  return false;
120
- };
121
-
122
- // @ts-expect-error
123
- const proxy = obj[COPY_ON_WRITE];
124
- if (proxy === undefined) {
125
- if (Array.isArray(obj)) {
126
- if (hasProxy(obj)) {
127
- // @ts-expect-error
128
- return obj.map((element) => copy(element));
129
- }
148
+ }
130
149
 
131
- if (isDeeplyNested(obj)) return structuredClone(obj);
132
- return [...obj] as T;
133
- }
150
+ if (depth > 0) {
151
+ return true;
152
+ }
134
153
 
135
- if (hasProxy(obj)) {
136
- const result = {} as T;
137
- for (const [key, value] of Object.entries(obj)) {
138
- // @ts-expect-error
139
- result[key] = copy(value);
140
- }
154
+ if (Array.isArray(obj)) {
155
+ return obj.some((element) => isDeeplyNested(element, depth + 1));
156
+ }
141
157
 
142
- return result;
158
+ for (const value of Object.values(obj)) {
159
+ if (isDeeplyNested(value, depth + 1)) {
160
+ return true;
143
161
  }
144
-
145
- // Note: spread operator is significantly faster than `structuredClone`
146
- if (isDeeplyNested(obj)) return structuredClone(obj);
147
- return { ...obj };
148
162
  }
149
163
 
150
- return proxy;
164
+ return false;
151
165
  };