Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions doc/v3/owl/reference/registries.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,22 @@ setup() {

### `delete(key)`

Removes an entry by key. Returns `void` (not chainable — unlike
`Resource.delete`).
Removes an entry by key. Returns the registry for chaining.

```js
views.delete("form");
views.delete("list").delete("kanban");
```

### `clear()`

Removes every entry. Returns `void` (not chainable, since there is nothing left
to operate on). Entries added with `use()` are removed as well: their scope
cleanup becomes a no-op, so nothing comes back when the component or plugin is
destroyed.

```js
views.clear();
```

### `has(key)`
Expand Down Expand Up @@ -200,7 +211,8 @@ See [Types & Validation](types_validation.md) for the full schema syntax.
| `use(key, value, { sequence?, force? })` | Add for the lifetime of the current component/plugin. Chainable. Throws outside a context, or on duplicate key unless `force: true`. |
| `useById(item, { sequence?, force? })` | Scoped variant of `addById`. Chainable. |
| `get(key, defaultValue?)` | Look up by key. Throws `OwlError` if missing and no default. |
| `delete(key)` | Remove. Returns `void`. |
| `delete(key)` | Remove. Chainable. |
| `clear()` | Remove every entry. Returns `void`. |
| `has(key)` | Test key presence. |
| `items()` | Reactive computed returning values sorted by sequence. |
| `entries()` | Reactive computed returning `[key, value]` tuples sorted by sequence. |
12 changes: 12 additions & 0 deletions doc/v3/owl/reference/resources.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,17 @@ commands.delete(item);
commands.delete(a).delete(b);
```

### `clear()`

Removes every item. Returns `void` (not chainable, since there is nothing left
to operate on). Items added with `use()` are removed as well: their scope
cleanup becomes a no-op, so nothing comes back when the component or plugin is
destroyed.

```js
commands.clear();
```

### `has(item)`

Returns `true` if the resource contains the given item (reference equality).
Expand Down Expand Up @@ -155,5 +166,6 @@ See [Types & Validation](types_validation.md) for the full schema syntax.
| `add(item, { sequence? })` | Add permanently. Chainable. |
| `use(item, { sequence? })` | Add for the lifetime of the current component/plugin. Chainable. Throws outside a context. |
| `delete(item)` | Remove by reference equality. Chainable. |
| `clear()` | Remove every item. Returns `void`. |
| `has(item)` | Test membership by reference equality. |
| `items()` | Reactive computed returning items sorted by sequence. |
7 changes: 6 additions & 1 deletion packages/owl-core/src/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,13 @@ export class Registry<T> {
return hasKey ? this._map()[key][1] : defaultValue!;
}

delete(key: string) {
delete(key: string): Registry<T> {
delete this._map()[key];
return this;
}

clear() {
this._map.set(Object.create(null));
}

has(key: string): boolean {
Expand Down
4 changes: 4 additions & 0 deletions packages/owl-core/src/resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ export class Resource<T> {
return this;
}

clear() {
this._items.set([]);
}

has(item: Item<T>): boolean {
return this._items().some(([s, value]) => value === item);
}
Expand Down
35 changes: 35 additions & 0 deletions packages/owl-core/tests/registry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,41 @@ describe("registry", () => {
registry.add("key", "some value");
expect(registry.get("key")).toBe("some value");
registry.delete("key");
expect(registry.has("key")).toBe(false);
});

test("delete method returns the registry, so it is chainable", () => {
const registry = new Registry();

registry.add("a", 1).add("b", 2).add("c", 3);
registry.delete("a").delete("b");
expect(registry.items()).toEqual([3]);
});

test("can remove every value", () => {
const registry = new Registry();

registry.add("key", "some value").add("other", "value");
registry.clear();
expect(registry.has("key")).toBe(false);
expect(registry.has("other")).toBe(false);
expect(registry.items()).toEqual([]);
registry.add("key", "again");
expect(registry.get("key")).toBe("again");
});

test("clear notifies effects", async () => {
const registry: Registry<string> = new Registry();
registry.add("key", "a");
const steps: string[][] = [];

effect(() => {
steps.push(registry.items());
});
expect(steps).toEqual([["a"]]);
registry.clear();
await waitScheduler();
expect(steps).toEqual([["a"], []]);
});

test("set method returns the registry, so it is chainable", () => {
Expand Down
24 changes: 24 additions & 0 deletions packages/owl-core/tests/resource.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,30 @@ test("can remove values", () => {
expect(resource.items()).toEqual(["c"]);
});

test("can remove every value", () => {
const resource = new Resource();
resource.add("a").add("b");
resource.clear();
expect(resource.items()).toEqual([]);
expect(resource.has("a")).toBe(false);
resource.add("c");
expect(resource.items()).toEqual(["c"]);
});

test("clear notifies effects", async () => {
const resource: Resource<string> = new Resource();
resource.add("a");
const steps: string[][] = [];

effect(() => {
steps.push(resource.items());
});
expect(steps).toEqual([["a"]]);
resource.clear();
await waitScheduler();
expect(steps).toEqual([["a"], []]);
});

test("sequence", async () => {
const resource = new Resource<string>({ name: "r" });

Expand Down