diff --git a/src/store.js b/src/store.js index b90fd01d..bc8b54c3 100644 --- a/src/store.js +++ b/src/store.js @@ -1028,6 +1028,15 @@ function get(Model, id) { try { let result = config.storage.get(id); + if ( + !(result instanceof Promise) && + (result === undefined || typeof result !== "object") + ) { + throw TypeError( + `Storage 'get' method must return a Promise, an instance, or null: ${result}`, + ); + } + if (typeof result !== "object" || result === null) { if (offline) offline.set(stringId, null); throw notFoundError(Model, stringId); @@ -1192,9 +1201,22 @@ function set(model, values = {}) { id = localModel ? localModel.id : model.id; - const result = Promise.resolve( - config.storage.set(isInstance ? id : undefined, localModel, keys), - ) + let result = config.storage.set( + isInstance ? id : undefined, + localModel, + keys, + ); + + if ( + !(result instanceof Promise) && + (result === undefined || typeof result !== "object") + ) { + throw TypeError( + `Storage 'set' method must return a Promise, an instance, or null: ${result}`, + ); + } + + result = Promise.resolve(result) .then((data) => { const resultModel = data === localModel ? localModel : config.create(data); @@ -1529,10 +1551,14 @@ function store(Model, options = {}) { let id = resolveId(host, value) || (value ? value.id : undefined); if (!id && (value === undefined || value === null)) { - const draftModel = draft.create({}); - id = draftModel.id; + if (config.enumerable) { + const draftModel = draft.create({}); + id = draftModel.id; - syncCache(draft, draftModel.id, draftModel, false); + syncCache(draft, draftModel.id, draftModel, false); + } else { + clear(draft.model); + } } return get(Model, id); diff --git a/test/spec/store.js b/test/spec/store.js index f0893cda..d30b875e 100644 --- a/test/spec/store.js +++ b/test/spec/store.js @@ -82,7 +82,6 @@ describe("store:", () => { store.get(Model, "1"); expect(() => store.get(Model.nestedArrayOfObjects)).toThrow(); }); - it("does not throw when nested array is used as other nested listing", () => { store.get(Model, "1"); expect(() => @@ -96,6 +95,18 @@ describe("store:", () => { expect(() => store.get({ nested: [() => {}] })).toThrow(); }); + it("set to an error state when get method returning undefined", () => { + Model = { + value: "test", + [store.connect]: { + get: () => undefined, + }, + }; + + const model = store.get(Model); + expect(store.error(model)).toBeInstanceOf(Error); + }); + it("returns a placeholder in error state for not defined model", () => { const model = store.get({ id: true }, "1"); expect(model).toBeInstanceOf(Object); @@ -389,6 +400,22 @@ describe("store:", () => { ) .catch((e) => expect(e).toBeInstanceOf(Error))); + fit("rejects an error when set method returning undefined", () => { + Model = { + value: "test", + [store.connect]: { + get: () => ({}), + set: () => { + return undefined; + }, + }, + }; + + return store.set(Model).catch((e) => { + expect(e).toBeInstanceOf(Error); + }); + }); + it("returns a placeholder in error state for not found singleton model", () => { Model = { value: "test", @@ -1432,7 +1459,9 @@ describe("store:", () => { Model = { value: "test", [store.connect]: { - get: () => {}, + get: () => { + return { value: "test 2" }; + }, set: (id, values) => values, }, }; @@ -1442,12 +1471,13 @@ describe("store:", () => { draft: store(Model, { draft: true }), }); el = document.createElement("test-store-factory-singleton-draft"); - expect(el.draft).toEqual({ value: "test" }); + + expect(el.draft).toEqual({ value: "test 2" }); return store.set(el.draft, { value: "other" }).then(() => { expect(el.draft).toEqual({ value: "other" }); el.draft = undefined; - expect(el.draft).toEqual({ value: "test" }); + expect(el.draft).toEqual({ value: "test 2" }); }); }); });