Skip to content

Instantly share code, notes, and snippets.

@wycats
Created October 25, 2022 23:11
Show Gist options
  • Save wycats/6800716eb6744f63d9b9396670d5c625 to your computer and use it in GitHub Desktop.
Save wycats/6800716eb6744f63d9b9396670d5c625 to your computer and use it in GitHub Desktop.

Making unique-id a importable function

The Use Cases

import { uniqueId } from "@ember/???";

<template>
  {{#let (unique-id) as |id|}}

  {{/let}}
</template>
import { uniqueId } from '@ember/???';

class MyThing {
  id = uniqueId();
}

The Constraints

  1. The behavior of (unique-id) in classic mode must be the same as the behavior of uniqueId() in <template> mode.
  2. The uniqueId function must be the same function in both use-cases described above.
  3. The result of uniqueId() in a <template> must not change after the expression was initially evaluated.
  4. Other importable "helpers": a. hard constraint: should eventually come from the same package name (or, some coherent package structure) b. soft constraint: people will find it weird if we ship uniqueId but not other similar helpers that are in a similar predicament.
  5. Modifiers and components should also ultimately be imported from a coherent package structure that includes whatever we do here.

Importable Things

Ember.Template.Helpers

Name Type In <template>? Importable?
action ☠️ ☠️ Uses this from template
array pure helper 😀 ✔️
hash pure helper 😀 ✔️
component 😀 ✔️
- takes dynamic string internal ☠️ ☠️
- take a component ??? 😵‍💫 ???
helper ???
modifier ???
concat pure helper 😀 ✔️
debugger control flow 😀 ✖️
each control flow 😀 ✖️
each-in control flow 😀 ✖️
fn probably keyword 😵‍💫 😵‍💫
get pure helper 😀 ✔️
has-block control flow 😀 ✖️
has-block-params control flow 😀 ✖️
#if control flow 😀 ✖️
if control flow 😀 ✖️
#unless control flow 😀 ✖️
unless control flow 😀 ✖️
in-element internal component 😀 ✖️
input classic component ☠️ ✖️
let control flow 😀 ✖️
link-to classic component ☠️ ✖️
log ???
mount control flow 😀 ✖️
mut keyword (references) ☠️ ?
on modifier 😀 ✔️ (maybe keyword)
outlet control flow 😀 ✖️
page-title ???
textarea classic component ☠️ ✖️
unbound legacy ☠️ ✖️
unique-id non-deterministic helper 😀 ✔️
yield control flow 😀 ✖️

NOTE: inline if and unless are control flow because they "auto-arrow" their expressions.

Importable Candidates

Meaningful in JS

Name Type In <template>? Importable? Meaningful in JS?
concat pure helper 😀 ✔️ ✔️
log non-deterministic helper ✔️ ✔️
unique-id non-deterministic helper 😀 ✔️ ✔️

Not Meaningful in JS

Name Type In <template>? Importable? Meaningful in JS?
mut keyword (references) ☠️ ? ✖️
on modifier 😀 ✔️ (maybe keyword) ✖️
page-title non-deterministic control flow ✖️

Unsure

Name Type In <template>? Importable? Meaningful in JS?
array pure helper 😀 ✔️ 🤔
hash pure helper 😀 ✔️ 🤔
get pure helper 😀 ✔️ 🤔

Maybe we want these to be keywords because they are effectively literal notation for objects and arrays.

Built-In Components

These are currently implemented as special Glimmer resolution rules, but we don't want to make them keywords in <template>, so they need to be importable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment