-
Notifications
You must be signed in to change notification settings - Fork 99
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
docs: Octane and much polish and clarification #935
Changes from 58 commits
0978813
d5bf2e2
6bd300a
6c1f58f
5b4d971
c1fc7a7
d19c2cb
b65a980
0204699
937b014
55289b5
d1b6e33
993acbb
e79d768
69bbb21
b9082c6
f9d4c41
8b17cc6
b54ff71
0fbadb8
698491b
ccd00ef
52d0ad1
b9f3c7b
701d763
a248694
42fe756
b7e4e99
14d031e
ed3970b
000184d
b6c8cd4
5847eea
568e17f
e91e2c0
65164e6
0f4f9fb
5766e28
2325dee
3b29e4f
9149904
6f247a6
169935f
b029a86
59b7861
bd8ee91
d4041b5
9e03eee
7e03549
43ed5e8
2b909d5
0bf5b58
bfeda3c
5acf6c1
356fc31
09edd28
601f0cb
0ca18d9
67fa036
5161e81
f010a3c
7165edf
3fcf219
657f25c
09314f8
bf86338
fe4e72e
8b7f386
d9ad89e
2df9346
891f258
108c561
38188ad
292765c
d641e26
7f57d0a
a0116b6
c89eb3c
25bc558
e704980
92a0bd5
0d24bc8
7da5e0e
dfc410b
745ae42
b46c16c
482b727
2811d5b
99bd07e
79fc492
dae619f
7758f88
d68b24b
4176b19
de57fb4
29f6414
0203bac
006c144
f618237
c864adc
3d6e42c
51ec9ac
78d169a
3ca1974
049b095
5543bba
8130565
1622992
adb53ab
3a434de
e55338e
4f1aa36
9a6c2c1
3734a03
7a43168
91f1556
ee8fae9
3d80a5f
3cd77bb
496fa76
4dcb2de
edafc5f
30eb350
0f9f088
1a593e8
f35db2b
83724cf
66256f1
979f16d
6d0f586
7d6628a
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 |
---|---|---|
@@ -0,0 +1,29 @@ | ||
name: Publish Draft Octane Docs | ||
|
||
on: | ||
push: | ||
branches: | ||
- octane-docs | ||
|
||
jobs: | ||
deploy-docs: | ||
name: Deploy Docs Preview | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout Code | ||
uses: actions/checkout@v1 | ||
- name: Install Node | ||
uses: actions/setup-node@v1 | ||
with: | ||
node-version: '^8.12' | ||
- name: Install Dependencies | ||
run: yarn install --frozen-lockfile | ||
- name: Set Git Identity | ||
run: | | ||
git config --global user.name "Tomster" | ||
git config --global user.email "[email protected]" | ||
- name: Publish Docs | ||
run: yarn ember deploy production | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
ADDON_DOCS_VERSION_PATH: 'octane-docs' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
// BEGIN-SNIPPET args-getter.ts | ||
import Component from '@glimmer/component'; | ||
|
||
export default class ArgsDisplay extends Component { | ||
get argNames(): string[] { | ||
return Object.keys(this.args); | ||
} | ||
} | ||
// END-SNIPPET |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
interface Dict<T = unknown> { | ||
[key: string]: T | undefined; | ||
} | ||
|
||
// BEGIN-SNIPPET show-all.ts | ||
import { helper } from '@ember/component/helper'; | ||
|
||
const describe = (entries: string): string => (entries.length > 0 ? entries : '(none)'); | ||
|
||
export function showAll(positional: unknown[], named: Dict) { | ||
// pretty print each item with its index, like `0: { neat: true }` or | ||
// `1: undefined`. | ||
const positionalEntries = positional | ||
.reduce<string[]>((items, arg, index) => items.concat(`${index}: ${JSON.stringify(arg)}`), []) | ||
.join(', '); | ||
|
||
// pretty print each item with its name, like `cool: beans` or | ||
// `answer: 42`. | ||
const namedEntries = Object.keys(named) | ||
.reduce<string[]>( | ||
(items, key) => items.concat(`${key}: ${JSON.stringify(named[key], undefined, 2)}`), | ||
[] | ||
) | ||
.join(', '); | ||
|
||
return `positional: ${describe(positionalEntries)}\nnamed: ${describe(namedEntries)}`; | ||
} | ||
|
||
export default helper(showAll); | ||
// END-SNIPPET |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
/** This exists just to support example code. */ | ||
export function generateUrl(): string { | ||
return ''; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// BEGIN-SNIPPET args-display.ts | ||
import Component from '@glimmer/component'; | ||
|
||
const log = console.log.bind(console); | ||
|
||
export default class ArgsDisplay extends Component { | ||
constructor(owner: unknown, args: {}) { | ||
super(owner, args); | ||
|
||
Object.keys(args).forEach(log); | ||
} | ||
} | ||
// END-SNIPPET |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// BEGIN-SNIPPET belongs-to.ts | ||
import Model, { belongsTo } from '@ember-data/model'; | ||
import DS from 'ember-data'; // NOTE: this is a workaround, see discussion below! | ||
import User from './user'; | ||
import Site from './site'; | ||
|
||
export default class Post extends Model { | ||
@belongsTo('user') | ||
user!: DS.PromiseObject<User>; | ||
|
||
@belongsTo('site', { async: false }) | ||
site!: Site; | ||
} | ||
// END-SNIPPET |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// BEGIN-SNIPPET cart-contents-bad.ts | ||
import Component from '@glimmer/component'; | ||
import { inject as service } from '@ember/service'; | ||
import { action } from '@ember/object'; | ||
|
||
import ShoppingCartService from 'my-app/services/shopping-cart'; | ||
|
||
export default class CartContentsComponent extends Component { | ||
@service shoppingCart: ShoppingCartService; | ||
|
||
@action | ||
remove(item) { | ||
// Error: Property 'saveForLater' does not exist on type 'ShoppingCartService'. | ||
this.shoppingCart.saveForLater(item); | ||
} | ||
}; | ||
// END-SNIPPET |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// BEGIN-SNIPPET cart-contents-lookup.ts | ||
import Component from '@glimmer/component'; | ||
import { getOwner } from '@ember/application'; | ||
import { action } from '@ember/object'; | ||
|
||
import ShoppingCartService from 'my-app/services/shopping-cart'; | ||
|
||
export default class CartContentsComponent extends Component { | ||
get cart() { | ||
return getOwner(this).lookup('service:shopping-cart') as ShoppingCartService; | ||
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. You mentioned it in the writeup, but let's be extra explicit that this cast is wildly unsafe and the user has to guarantee it. If they typo the lookup, they'll get back It occurs to me that we could improve this by defining an 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. Definitely would be good to be extra explicit here. I was thinking the exact same thing about a registry for this. 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. I opened an issue on the RFCs repo for that idea, and will hopefully 🤞 write an actual RFC for it if there's interest. 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. RFC #585 for the above concern! |
||
} | ||
|
||
@action | ||
remove(item) { | ||
this.cart.remove(item); | ||
} | ||
}; | ||
// END-SNIPPET |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,16 @@ | ||||||
// BEGIN-SNIPPET cart-contents.ts | ||||||
import Component from '@glimmer/component'; | ||||||
import { inject as service } from '@ember/service'; | ||||||
import { action } from '@ember/object'; | ||||||
|
||||||
import ShoppingCartService from 'my-app/services/shopping-cart'; | ||||||
|
||||||
export default class CartContentsComponent extends Component { | ||||||
@service shoppingCart: ShoppingCartService; | ||||||
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.
Suggested change
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. I'll also explain this. |
||||||
|
||||||
@action | ||||||
remove(item) { | ||||||
this.shoppingCart.remove(item); | ||||||
} | ||||||
}; | ||||||
// END-SNIPPET |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
// BEGIN-SNIPPET dict-usage.ts | ||
let ages: Dict<number> = { | ||
chris: 32, | ||
}; | ||
|
||
let johnAge = ages['john']; // undefined | ||
let chrisAge = ages['chris']; // 32 | ||
// END-SNIPPET |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
// BEGIN-SNIPPET dict.ts | ||
interface Dict<T = unknown> { | ||
[key: string]: T | undefined; | ||
} | ||
// END-SNIPPET |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
declare module '@ember/debug' { | ||
export function assert(message: string, value: unknown): asserts value; | ||
} | ||
|
||
// BEGIN-SNIPPET function-based-helper.ts | ||
import { helper } from '@ember/component/helper'; | ||
import { assert } from '@ember/debug'; | ||
import { is } from '../../type-utils' | ||
|
||
export function join(positional: [unknown, unknown], named: Dict<unknown>) { | ||
assert( | ||
`'join' requires two 'string' positional parameters`, | ||
is<[string, string]>( | ||
positional, | ||
positional.length === 2 && | ||
positional.every(el => typeof el === 'string') | ||
) | ||
); | ||
assert(`'join' requires argument 'separator'`, typeof named.separator === 'string'); | ||
|
||
const joined = positional.join(named.separator); | ||
const prefix = typeof named.prefix === 'string' ? named.prefix : ''; | ||
|
||
return `${prefix}${joined}`; | ||
} | ||
|
||
export default helper(join); | ||
// END-SNIPPET |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// BEGIN-SNIPPET has-many.ts | ||
import Model, { hasMany } from '@ember-data/model'; | ||
import EmberArray from '@ember/array'; | ||
import DS from 'ember-data'; // NOTE: this is a workaround, see discussion below! | ||
import Comment from './comment'; | ||
import User from './user'; | ||
|
||
export default class Thread extends Model { | ||
@hasMany('comment') | ||
comment!: DS.PromiseManyArray<Comment>; | ||
|
||
@hasMany('user', { async: false }) | ||
participants!: EmberArray<User>; | ||
} | ||
// END-SNIPPET |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// BEGIN-SNIPPET shopping-cart.ts | ||
import { A } from '@ember/array'; | ||
import Service from '@ember/service'; | ||
|
||
export default class ShoppingCartService extends Service { | ||
items = A([]); | ||
|
||
add(item) { | ||
this.items.pushObject(item); | ||
} | ||
|
||
remove(item) { | ||
this.items.removeObject(item); | ||
} | ||
|
||
empty() { | ||
this.items.clear(); | ||
} | ||
} | ||
// END-SNIPPET |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
// BEGIN-SNIPPET simplified-glimmer-component.d.ts | ||
export default class Component<Args extends {} = {}> { | ||
args: Args; | ||
|
||
constructor(owner: unknown, args: Args); | ||
} | ||
// END-SNIPPET |
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.