Skip to content

Commit

Permalink
Fix glint types
Browse files Browse the repository at this point in the history
  • Loading branch information
NullVoxPopuli committed Jul 25, 2023
1 parent 77d54e6 commit 48f981c
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 45 deletions.
8 changes: 4 additions & 4 deletions ember-resources/src/core/function-based/manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import { invokeHelper } from '@ember/helper';
import { capabilities as helperCapabilities } from '@ember/helper';
import { dependencySatisfies, importSync, macroCondition } from '@embroider/macros';

import { CURRENT, Reactive, ReadonlyCell } from '../../util/cell';
import { INTERNAL } from './types';
import { ReadonlyCell } from '../../util/cell';
import { CURRENT, INTERNAL } from './types';

import type { Cache, Destructor, InternalFunctionResourceConfig, ResourceFunction } from './types';
import type { ResourceAPI } from './types';
Expand Down Expand Up @@ -123,8 +123,8 @@ class FunctionResourceManager {
return maybeValue();
}

if (maybeValue instanceof Reactive) {
return maybeValue[CURRENT]();
if (CURRENT in maybeValue) {
return maybeValue[CURRENT];
}

return maybeValue;
Expand Down
21 changes: 20 additions & 1 deletion ember-resources/src/core/function-based/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,28 @@ export interface InternalFunctionResourceConfig<Value = unknown> {
[INTERNAL]: true;
}

export const CURRENT = Symbol('ember-resources::CURRENT');

export interface GlintRenderable {
/**
* Cells aren't inherently understood by Glint,
* so to work around that, we'll hook in to the fact that
* ContentValue (the type expected for all renderables),
* defines an interface with this signature.
*
* (SafeString)
*
* There *has* been interest in the community to formally support
* toString and toHTML APIs across all objects. An RFC needs to be
* written so that we can gather feedback / potential problems.
*/
toHTML(): string;
}

// Will need to be a class for .current flattening / auto-rendering
export interface Reactive<Value> {
export interface Reactive<Value> extends GlintRenderable {
current: Value;
[CURRENT]: Value;
[Invoke]?: Value;
}

Expand Down
19 changes: 9 additions & 10 deletions ember-resources/src/core/use.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { associateDestroyableChild } from '@ember/destroyable';
// @ts-ignore
import { invokeHelper } from '@ember/helper';

import { ReadonlyCell } from '../util/cell';
import { INTERNAL } from './function-based/types';
import { normalizeThunk } from './utils';

Expand Down Expand Up @@ -120,19 +121,17 @@ function classContextLink<Value>(
): Reactive<Value> {
let cache: ReturnType<typeof invokeHelper>;

return {
get current() {
if (!cache) {
cache = invokeHelper(context, definition);
return new ReadonlyCell<Value>(() => {
if (!cache) {
cache = invokeHelper(context, definition);

associateDestroyableChild(context, cache);
}
associateDestroyableChild(context, cache);
}

let value = getValue(cache);
let value = getValue(cache);

return getCurrentValue(value);
},
};
return getCurrentValue(value);
});
}

function argumentToDecorator<Value>(definition: Value | (() => Value)): PropertyDecorator {
Expand Down
44 changes: 14 additions & 30 deletions ember-resources/src/util/cell.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,20 @@
import { tracked } from '@glimmer/tracking';
import { assert } from '@ember/debug';

interface GlintRenderable {
/**
* Cells aren't inherently understood by Glint,
* so to work around that, we'll hook in to the fact that
* ContentValue (the type expected for all renderables),
* defines an interface with this signature.
*
* (SafeString)
*
* There *has* been interest in the community to formally support
* toString and toHTML APIs across all objects. An RFC needs to be
* written so that we can gather feedback / potential problems.
*/
toHTML(): string;
}

export const CURRENT = Symbol('ember-resources::CURRENT');

export abstract class Reactive<Value> {
abstract [CURRENT](): Value;
}

export class ReadonlyCell<Value> extends Reactive<Value> {
export class ReadonlyCell<Value> implements Reactive<Value> {
#getter: () => Value;

constructor(getter: () => Value) {
super();

this.#getter = getter;
}

[CURRENT](): Value {
toHTML(): string {
assert(
'Not a valid API. Please access either .current or .read() if the value of this Cell is needed'
);
}

get [CURRENT](): Value {
return this.current;
}

Expand All @@ -41,10 +23,10 @@ export class ReadonlyCell<Value> extends Reactive<Value> {
}
}

export class Cell<Value = unknown> extends Reactive<Value> implements GlintRenderable {
export class Cell<Value = unknown> implements Reactive<Value> {
@tracked declare current: Value;

[CURRENT](): Value {
get [CURRENT](): Value {
return this.current;
}

Expand All @@ -57,8 +39,6 @@ export class Cell<Value = unknown> extends Reactive<Value> implements GlintRende
constructor();
constructor(initialValue: Value);
constructor(initialValue?: Value) {
super();

if (initialValue !== undefined) {
this.current = initialValue;
}
Expand Down Expand Up @@ -162,6 +142,10 @@ export function cell<Value = unknown>(initialValue?: Value): Cell<Value> {
// @ts-ignore
import { capabilities as helperCapabilities, setHelperManager } from '@ember/helper';

import { CURRENT } from '../core/function-based/types';

import type { GlintRenderable, Reactive } from '../core/function-based/types';

class CellManager {
capabilities = helperCapabilities('3.23', {
hasValue: true,
Expand Down

0 comments on commit 48f981c

Please sign in to comment.