I've written a library that relies on equality checks. Example:
export class Item {
constructor(opts) {
if (typeof opts.name !== 'string') throw new TypeError('Name should be a string');
if (!opts.name) throw new Error('Please give item a name');
this.name = opts.name;
this.active = typeof opts.active === 'boolean' ? opts.active : false;
}
activate() {
this.active = true;
}
deactivate() {
this.active = false;
}
}
export class Stage {
constructor(opts) {
this.items = [];
}
add(item) {
this.items.push(item);
}
activate(itemToActivate) {
// Strict equality check here
const found = this.items.find(i => i === itemToActivate);
if (!found) throw new Error('Item "${itemToActivate.name}" not found');
found.activate();
}
}
Using this library could look like this:
import { Item, Stage } from 'lib.js';
const stage = new Stage();
const item1 = new Item({ name: 'one' });
const item2 = new Item({ name: 'two' });
stage.add(item1);
stage.add(item2);
stage.activate(item2);
This all works fine, but I'm running into issues when using this library in a framework that works with proxied objects like Vue 3, since I'm using a strict equality test in the activate method of the Stage class.
For example, in Vue 3:
<script>
import { Item, Stage } from 'lib.js';
export default {
data() {
return {
stage: null,
};
},
created() {
this.stage = new Stage();
const item1 = new Item({ name: 'one' });
const item2 = new Item({ name: 'two' });
stage.add(item1);
stage.add(item2);
stage.activate(item2); // This will throw an error `Item "two" not found`
}
}
</script>
<template>
<div v-if="stage">
<div>Items:</div>
<div v-for="(item, idx) in stage.items">{{ item.name }}</div>
</div>
<template>
From what I understand, Vue 3 and other frameworks' use of Proxy introduce a caveat to be aware of: the proxied object is not equal to the original object in terms of identity comparison (===), which is why activate throws an Error.
My question is: how do I update my library so it supports Proxy-based frameworks without using any framework helpers like toRaw which would make my library dependent on that framework?
toRaw()). Otherwise, you'll need toReflecton those properties and test each individually for equality.Itembeing proxied, but I need assistance on how to circumvent the strict equality error.Reflect)stage? If it's the originalnew Stage(), it should work. If it'sthis.stage, you also would need to refer tothis.stage.items[1]for that item that you activate.