Skip to content

Commit b43dcc0

Browse files
committed
Fix context types to be compatible with WCCG context protocol types.
1 parent bd88137 commit b43dcc0

4 files changed

Lines changed: 100 additions & 1 deletion

File tree

.changeset/fluffy-garlics-smash.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@lit/context': patch
3+
---
4+
5+
Fix context types to be compatible with WCCG context protocol types.

packages/context/src/lib/context-request-event.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export class ContextRequestEvent<C extends Context<unknown, unknown>>
5353
{
5454
readonly context: C;
5555
readonly callback: ContextCallback<ContextType<C>>;
56-
readonly subscribe: boolean;
56+
readonly subscribe?: boolean;
5757

5858
/**
5959
*
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* @license
3+
* Copyright 2021 Google LLC
4+
* SPDX-License-Identifier: BSD-3-Clause
5+
*/
6+
7+
import {ContextRequestEvent, Context} from './protocol-types.js';
8+
import {ContextRequestEvent as LitContextRequestEvent} from '../lib/context-request-event.js';
9+
import {Context as LitContext} from '../index.js';
10+
11+
/*
12+
* These function definitions check whether the Lit and protocol types are
13+
* compatible.
14+
*/
15+
16+
export const protocolFunction = (
17+
e: ContextRequestEvent<Context<unknown, unknown>>
18+
) => {
19+
litFunction(e);
20+
};
21+
22+
export const litFunction = (
23+
e: LitContextRequestEvent<LitContext<unknown, unknown>>
24+
) => {
25+
protocolFunction(e);
26+
};
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Copied from https://github.com/webcomponents-cg/community-protocols/blob/main/proposals/context.md#definitions
2+
// at 43f8158a75446af25164ff35d1a6b4f9e96e9d36
3+
4+
/**
5+
* A context key.
6+
*
7+
* A context key can be any type of object, including strings and symbols. The
8+
* Context type brands the key type with the `__context__` property that
9+
* carries the type of the value the context references.
10+
*/
11+
export type Context<KeyType, ValueType> = KeyType & {__context__: ValueType};
12+
13+
/**
14+
* An unknown context type
15+
*/
16+
export type UnknownContext = Context<unknown, unknown>;
17+
18+
/**
19+
* A helper type which can extract a Context value type from a Context type
20+
*/
21+
export type ContextType<T extends UnknownContext> =
22+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
23+
T extends Context<infer _, infer V> ? V : never;
24+
25+
/**
26+
* A function which creates a Context value object
27+
*/
28+
export const createContext = <ValueType>(key: unknown) =>
29+
key as Context<typeof key, ValueType>;
30+
31+
/**
32+
* A callback which is provided by a context requester and is called with the value satisfying the request.
33+
* This callback can be called multiple times by context providers as the requested value is changed.
34+
*/
35+
export type ContextCallback<ValueType> = (
36+
value: ValueType,
37+
unsubscribe?: () => void
38+
) => void;
39+
40+
/**
41+
* An event fired by a context requester to signal it desires a named context.
42+
*
43+
* A provider should inspect the `context` property of the event to determine if it has a value that can
44+
* satisfy the request, calling the `callback` with the requested value if so.
45+
*
46+
* If the requested context event contains a truthy `subscribe` value, then a provider can call the callback
47+
* multiple times if the value is changed, if this is the case the provider should pass an `unsubscribe`
48+
* function to the callback which requesters can invoke to indicate they no longer wish to receive these updates.
49+
*/
50+
export class ContextRequestEvent<T extends UnknownContext> extends Event {
51+
public constructor(
52+
public readonly context: T,
53+
public readonly callback: ContextCallback<ContextType<T>>,
54+
public readonly subscribe?: boolean
55+
) {
56+
super('context-request', {bubbles: true, composed: true});
57+
}
58+
}
59+
60+
declare global {
61+
interface HTMLElementEventMap {
62+
/**
63+
* A 'context-request' event can be emitted by any element which desires
64+
* a context value to be injected by an external provider.
65+
*/
66+
'context-request': ContextRequestEvent<Context<unknown, unknown>>;
67+
}
68+
}

0 commit comments

Comments
 (0)