diff --git a/packages/polyfill/e2e/polyfill-entry.ts b/packages/polyfill/e2e/polyfill-entry.ts index 07dc5a8..af4e222 100644 --- a/packages/polyfill/e2e/polyfill-entry.ts +++ b/packages/polyfill/e2e/polyfill-entry.ts @@ -1088,9 +1088,11 @@ const identity = new IdentityStore( // `data` - the member its own example destructures first, and one of the three that // used to come back unfiltered. const read = (): string[] => - [...(libUseShape(wsShape("urn:e2e:caps:Item"), EVERYTHING).data as Iterable)].map( - (i) => i.v, - ); + [ + ...(libUseShape(wsShape("urn:e2e:caps:Item"), EVERYTHING).data as Iterable< + { v: string } + >), + ].map((i) => i.v); setCurrentUser("owner-O"); getCaps().open("did:ng:o:protdoc", "protected"); const link = getCaps().open("did:ng:o:pubdoc", "public"); diff --git a/packages/polyfill/src/emulated-verifier/read-filter.ts b/packages/polyfill/src/emulated-verifier/read-filter.ts index 0b1875b..8155007 100644 --- a/packages/polyfill/src/emulated-verifier/read-filter.ts +++ b/packages/polyfill/src/emulated-verifier/read-filter.ts @@ -213,6 +213,12 @@ export function makeReadFilteredView(set: S, caps: CapRegistry * `DeepSignal` instead of a `DeepSignalSet`, and an array is addressed by * INDEX and counts itself with `length`. Decided from the target once, so the view never * grows a member the collection it wraps does not have. + * + * MEASURED against the real `@ng-org/alien-deepsignals` rather than assumed, because the + * collection is itself a proxy and what it answers for a key it does not carry is its + * business: `deepSignal(new Set(...)).length` is `undefined` and its `Object.keys` is + * empty, while `deepSignal([...]).length` is a number. So the set form never enters this + * branch, and the set form is also the one with no key naming an item to project. */ const arrayLike = typeof (set as { length?: unknown }).length === "number"; /** The index a key names, or `null` when it names no position in this collection. */ diff --git a/packages/polyfill/test/read-filter.test.ts b/packages/polyfill/test/read-filter.test.ts index 7d11704..e936db6 100644 --- a/packages/polyfill/test/read-filter.test.ts +++ b/packages/polyfill/test/read-filter.test.ts @@ -149,10 +149,10 @@ test("forEach is filtered too", () => { // hatch included, which `get` refuses by name. Everything built on that call goes the same // way: `Object.keys`, `Object.entries`, a spread, `JSON.stringify`, a console inspection. test("a descriptor cannot answer what reading the member refuses", () => { - const set = new Set([MINE]) as any; + const set: Set & { __raw__?: unknown } = new Set([MINE]); set.__raw__ = set; const { caps, become } = setup("alice"); - const view = makeReadFilteredView(set, caps) as any; + const view = makeReadFilteredView(set, caps); become("bob"); expect(() => Object.getOwnPropertyDescriptor(view, "__raw__")).toThrow(/raw collection/i); }); @@ -163,9 +163,9 @@ test("a descriptor cannot answer what reading the member refuses", () => { // count of what a holder may NOT read came back out through the other three, and the // descriptor handed back the items themselves. test("the array form counts and addresses the readable items, by every route", () => { - const items = [MINE, FOREIGN, LINKED]; + const items: Item[] = [MINE, FOREIGN, LINKED]; const { caps, become } = setup("alice"); - const view = makeReadFilteredView(items, caps) as any; + const view = makeReadFilteredView(items, caps); become("bob"); // holds nothing of the three documents expect(view.length).toBe(0); @@ -178,9 +178,9 @@ test("the array form counts and addresses the readable items, by every route", ( become("alice"); // holds her own document and the one she published expect(view.length).toBe(2); expect(Object.keys(view)).toEqual(["0", "1"]); - expect(view[0].id).toBe("a"); - expect(view[1].id).toBe("p"); - expect(Object.getOwnPropertyDescriptor(view, "1")?.value.id).toBe("p"); + expect(view[0]).toBe(MINE); + expect(view[1]).toBe(LINKED); + expect(Object.getOwnPropertyDescriptor(view, "1")?.value).toBe(LINKED); expect(2 in view).toBe(false); // `length` is the array's own key and is never hidden - a proxy may not drop a key the // target cannot configure away - but it is not a position and does not enumerate.