A watch attribute that only has a set (e.g. an updatedAt timestamp) shows up as undefined on reads when it isn't stored on the item.
The fix is to treat watchers per method: only run a watcher on get if it defines a get, and on set if it defines a set.
Version: 3.9.0
Model
{
model: { entity: "watcherItem", service: "Playground", version: "1" },
attributes: {
id: { type: "string", required: true },
name: { type: "string", required: true },
updatedAt: { type: "number", watch: "*", set: () => Date.now() },
},
indexes: {
byId: {
pk: { field: "pk", composite: ["id"] },
sk: { field: "sk", composite: ["id"] },
},
},
}
Repro
const result = entity.parse({
Item: {
pk: "$playground#id_123",
sk: "$watcheritem_1#id_123",
id: "123",
name: "test", // updatedAt not stored
},
});
"updatedAt" in result.data; // true, expected false
Object.keys(result.data); // ['id', 'name', 'updatedAt']
Same thing happens on .get().go() for items missing the value (e.g. records written before the watcher existed). A projection that excludes the attribute hides it, since the key gets filtered out afterward.
Expected
updatedAt shouldn't appear at all when it's not stored and has no getter. Watchers with a getter should still run on reads, and setter watchers should still generate on writes.
A
watchattribute that only has aset(e.g. anupdatedAttimestamp) shows up asundefinedon reads when it isn't stored on the item.The fix is to treat watchers per method: only run a watcher on
getif it defines aget, and onsetif it defines aset.Version: 3.9.0
Model
Repro
Same thing happens on
.get().go()for items missing the value (e.g. records written before the watcher existed). A projection that excludes the attribute hides it, since the key gets filtered out afterward.Expected
updatedAtshouldn't appear at all when it's not stored and has no getter. Watchers with a getter should still run on reads, and setter watchers should still generate on writes.