-
Notifications
You must be signed in to change notification settings - Fork 392
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(wire-service): imported function identifier as adapter id for @wire #26
Changes from all commits
b020689
d533399
ffe55db
efebc1b
daa9873
b46ef01
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,9 +12,9 @@ describe('Wired field', () => { | |
export default class Test {} | ||
Test.wire = { | ||
innerRecord: { | ||
type: "record", | ||
params: { recordId: "recordId" }, | ||
static: { fields: ["Account", 'Rate'] } | ||
static: { fields: ["Account", 'Rate'] }, | ||
type: "record" | ||
} | ||
}; | ||
`); | ||
|
@@ -31,17 +31,37 @@ describe('Wired field', () => { | |
}, | ||
}); | ||
|
||
test('decorator expects a string as first parameter', ` | ||
test('decorator expects a function identifier as first parameter', ` | ||
import { wire } from 'engine'; | ||
import { record } from 'data-service'; | ||
export default class Test { | ||
@wire(record, {}) innerRecord; | ||
} | ||
`, ` | ||
import { wire } from 'engine'; | ||
import { record } from 'data-service'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as 36 |
||
export default class Test {} | ||
Test.wire = { | ||
innerRecord: { | ||
params: {}, | ||
static: {}, | ||
adapter: record | ||
} | ||
}; | ||
`); | ||
|
||
test('decorator expects an imported identifier as first parameter', ` | ||
import { wire } from 'engine'; | ||
const RECORD = "record" | ||
export default class Test { | ||
@wire(RECORD, {}) innerRecord; | ||
} | ||
`, undefined, { | ||
message: 'test.js: @wire expects a string as first parameter.', | ||
loc: { | ||
line: 3, | ||
column: 10, | ||
}, | ||
message: 'test.js: @wire expects a function identifier to be imported as first parameter.', | ||
loc: { | ||
line: 4, | ||
column: 6, | ||
}, | ||
}); | ||
|
||
test('decorator expects an oject as second parameter', ` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not you but we have a typo in object (missing b) |
||
|
@@ -69,9 +89,9 @@ describe('Wired method', () => { | |
} | ||
Test.wire = { | ||
innerRecordMethod: { | ||
type: "record", | ||
params: { recordId: "recordId" }, | ||
static: { fields: ["Account", 'Rate'] }, | ||
type: "record", | ||
method: 1 | ||
} | ||
}; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,10 +31,6 @@ module.exports = function wireVisitor ({ types: t }) { | |
function buildWireConfigValue(wiredValues) { | ||
return t.objectExpression(wiredValues.map(wiredValue => { | ||
const wireConfig = [ | ||
t.objectProperty( | ||
t.identifier('type'), | ||
t.stringLiteral(wiredValue.type) | ||
), | ||
t.objectProperty( | ||
t.identifier('params'), | ||
t.objectExpression(wiredValue.params) | ||
|
@@ -45,6 +41,25 @@ module.exports = function wireVisitor ({ types: t }) { | |
) | ||
]; | ||
|
||
// TODO: deprecate type (string as adapter id once consumer has migrated to use imported identifier) | ||
if (wiredValue.type) { | ||
wireConfig.push( | ||
t.objectProperty( | ||
t.identifier('type'), | ||
t.stringLiteral(wiredValue.type) | ||
) | ||
) | ||
} | ||
|
||
if (wiredValue.adapter) { | ||
wireConfig.push( | ||
t.objectProperty( | ||
t.identifier('adapter'), | ||
t.identifier(wiredValue.adapter) | ||
) | ||
) | ||
} | ||
|
||
if (wiredValue.isClassMethod) { | ||
wireConfig.push( | ||
t.objectProperty( | ||
|
@@ -72,9 +87,16 @@ module.exports = function wireVisitor ({ types: t }) { | |
); | ||
} | ||
|
||
if (!id.isStringLiteral()) { | ||
// TODO: deprecate string as adapter id once consumer has migrated to use imported identifier | ||
if (!id.isStringLiteral() && !id.isIdentifier()) { | ||
throw id.buildCodeFrameError( | ||
`@wire expects a string or a function identifier as first parameter.` | ||
); | ||
} | ||
|
||
if (id.isIdentifier() && !path.scope.getBinding(id.node.name).path.isImportSpecifier()) { | ||
throw id.buildCodeFrameError( | ||
`@wire expects a string as first parameter.` | ||
`@wire expects a function identifier to be imported as first parameter.` | ||
); | ||
} | ||
|
||
|
@@ -89,13 +111,21 @@ module.exports = function wireVisitor ({ types: t }) { | |
kind: 'method' | ||
}); | ||
|
||
wiredValues.push({ | ||
const wiredValue = { | ||
propertyName, | ||
isClassMethod, | ||
type: id.node.value, | ||
static: getWiredStatic(config), | ||
params: getWiredParams(config), | ||
}); | ||
} | ||
|
||
// TODO: deprecate type (string as adapter id once consumer has migrated to use imported identifier) | ||
if (id.isStringLiteral()) { | ||
wiredValue.type = id.node.value; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. perhaps we can extract id.node reference into a local variable, there are multiple accesses in this file. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we could, but |
||
} else if (id.isIdentifier()) { | ||
wiredValue.adapter = id.node.name; | ||
} | ||
|
||
wiredValues.push(wiredValue); | ||
|
||
path.remove(); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,9 @@ | ||
import { Element } from 'engine'; | ||
|
||
import { serviceTodo } from 'todo'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: s/serviceTodo/getTodo/ |
||
export default class WiredProp extends Element { | ||
@api todoId; | ||
|
||
@wire('todo', { id: '$todoId' }) | ||
@wire(serviceTodo, { id: '$todoId' }) | ||
todo; | ||
|
||
get error() { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
(function (global, factory) { | ||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : | ||
typeof define === 'function' && define.amd ? define(['exports'], factory) : | ||
(factory((global.Todo = {}))); | ||
}(this, (function (exports) { | ||
'use strict'; | ||
|
||
function getSubject(initialValue, initialError) { | ||
var observer; | ||
|
||
function next(value) { | ||
observer.next(value); | ||
} | ||
|
||
function error(err) { | ||
observer.error(err); | ||
} | ||
|
||
function complete() { | ||
observer.complete(); | ||
} | ||
|
||
var observable = { | ||
subscribe: function(obs) { | ||
observer = obs; | ||
if (initialValue) { | ||
next(initialValue); | ||
} | ||
if (initialError) { | ||
error(initialError); | ||
} | ||
return { | ||
unsubscribe: function() {} | ||
}; | ||
} | ||
}; | ||
|
||
return { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. there will be an error if someone calls next / error/ or complete before calling observable(); Your observer is undefined until subscribe is invoked. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is not exposed, the only thing that the module exposes is |
||
next: next, | ||
error: error, | ||
complete: complete, | ||
observable: observable | ||
}; | ||
} | ||
|
||
function generateTodo(id, completed) { | ||
return { | ||
id: id, | ||
title: 'task ' + id, | ||
completed: completed | ||
}; | ||
} | ||
|
||
var TODO = [ | ||
generateTodo(0, true), | ||
generateTodo(1, false), | ||
// intentionally skip 2 | ||
generateTodo(3, true), | ||
generateTodo(4, true), | ||
// intentionally skip 5 | ||
generateTodo(6, false), | ||
generateTodo(7, false) | ||
].reduce(function(acc, value) { | ||
acc[value.id] = value; | ||
return acc; | ||
}, {}); | ||
|
||
|
||
function serviceTodo(config) { | ||
if (!('id' in config)) { | ||
return undefined; | ||
} | ||
|
||
var todo = TODO[config.id]; | ||
if (!todo) { | ||
var subject = getSubject(undefined, { message: 'Todo not found' }); | ||
return subject.observable; | ||
} | ||
|
||
return getSubject(todo).observable; | ||
} | ||
|
||
exports.serviceTodo = serviceTodo; | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
}))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: s/record/getRecord/. That's the format we're using per https://salesforce.quip.com/tpa5AVyZ21kc