From c788082e18a833aa764e5108d110090bdced8988 Mon Sep 17 00:00:00 2001 From: Steve Rice Date: Fri, 24 Jan 2025 13:49:00 -0800 Subject: [PATCH] Promote `state-accessor` functions from experimental to supported (#5699) These reusable state accessors were added in 3eed29834600d02c6a1ab3dd039188edf0fb2951 under the `experimental` namespace. They are now considered ready to be promoted out to the `@typespec/compiler` package exports (and to have their `unsafe_` prefixes removed). In this commit, we move `state-accessor` into `utils` and add it to the module index so that its functions can be imported from `@typespec/compiler/utils`. For usages inside `@typespec/compiler`, we are replacing the wrapper functions in `lib/utils` with direct imports of the newly-exposed accessor functions. Because the wrapper functions previously created a symbol with the `TypeSpec.` prefix when given a string, we preserve this behavior by introducing the simple `createStateSymbol` function in files that previously used the wrapper functions. `createStateSymbol` could be trivially refactored into a shared utility function rather than duplicated, but here we are simply following the pattern already established where there are already several copies of this function. Indeed, while one of these was exported in 050139d2e272bb0b1f4d02010276a554c0b4ddc4, that export was never used. --- ...romote-state-accessor-2025-0-23-9-50-42.md | 12 ++++++ packages/compiler/src/core/visibility/core.ts | 16 +++++--- packages/compiler/src/experimental/index.ts | 12 ++++-- packages/compiler/src/lib/decorators.ts | 40 ++++++++++++------- packages/compiler/src/lib/encoded-names.ts | 9 +++-- packages/compiler/src/lib/key.ts | 8 +++- packages/compiler/src/lib/paging.ts | 9 +++-- packages/compiler/src/lib/service.ts | 2 +- packages/compiler/src/lib/utils.ts | 15 +------ packages/compiler/src/lib/visibility.ts | 9 ++++- packages/compiler/src/utils/index.ts | 1 + .../{experimental => utils}/state-accessor.ts | 8 +--- packages/events/src/decorators.ts | 8 ++-- packages/json-schema/src/decorators.ts | 17 ++++---- packages/json-schema/src/utils.ts | 4 +- packages/openapi/src/decorators.ts | 9 ++--- packages/sse/src/decorators.ts | 6 +-- packages/streams/src/decorators.ts | 4 +- 18 files changed, 108 insertions(+), 81 deletions(-) create mode 100644 .chronus/changes/promote-state-accessor-2025-0-23-9-50-42.md rename packages/compiler/src/{experimental => utils}/state-accessor.ts (84%) diff --git a/.chronus/changes/promote-state-accessor-2025-0-23-9-50-42.md b/.chronus/changes/promote-state-accessor-2025-0-23-9-50-42.md new file mode 100644 index 0000000000..ec051145e7 --- /dev/null +++ b/.chronus/changes/promote-state-accessor-2025-0-23-9-50-42.md @@ -0,0 +1,12 @@ +--- +changeKind: deprecation +packages: + - "@typespec/compiler" + - "@typespec/events" + - "@typespec/json-schema" + - "@typespec/openapi" + - "@typespec/sse" + - "@typespec/streams" +--- + +Deprecate `unsafe_useStateMap` and `unsafe_useStateSet`, export `useStateMap` and `useStateSet` \ No newline at end of file diff --git a/packages/compiler/src/core/visibility/core.ts b/packages/compiler/src/core/visibility/core.ts index b6e88b68d3..6a301a412c 100644 --- a/packages/compiler/src/core/visibility/core.ts +++ b/packages/compiler/src/core/visibility/core.ts @@ -29,7 +29,7 @@ import { } from "./lifecycle.js"; import type { VisibilityFilter as GeneratedVisibilityFilter } from "../../../generated-defs/TypeSpec.js"; -import { useStateMap, useStateSet } from "../../lib/utils.js"; +import { useStateMap, useStateSet } from "../../utils/index.js"; export { GeneratedVisibilityFilter }; @@ -38,13 +38,17 @@ export { GeneratedVisibilityFilter }; */ type VisibilityModifiers = Map>; +function createStateSymbol(name: string) { + return Symbol.for(`TypeSpec.${name}`); +} + /** * The global visibility store. * * This store is used to track the visibility modifiers */ const [getVisibilityStore, setVisibilityStore] = useStateMap( - "visibilityStore", + createStateSymbol("visibilityStore"), ); /** @@ -99,13 +103,13 @@ function getOrInitializeActiveModifierSetForClass( const VISIBILITY_PROGRAM_SEALS = new WeakSet(); const [isVisibilitySealedForProperty, sealVisibilityForProperty] = useStateSet( - "propertyVisibilitySealed", + createStateSymbol("propertyVisibilitySealed"), ); const [getSealedVisibilityClasses, setSealedVisibilityClasses] = useStateMap< ModelProperty, Set ->("sealedVisibilityClasses"); +>(createStateSymbol("sealedVisibilityClasses")); /** * Seals visibility modifiers for a property in a given visibility class. @@ -133,7 +137,7 @@ function sealVisibilityModifiersForClass( * Stores the default modifier set for a given visibility class. */ const [getDefaultModifiers, setDefaultModifiers] = useStateMap>( - "defaultVisibilityModifiers", + createStateSymbol("defaultVisibilityModifiers"), ); /** @@ -205,7 +209,7 @@ function groupModifiersByVisibilityClass(modifiers: EnumMember[]): Map("legacyVisibility"); + useStateMap(createStateSymbol("legacyVisibility")); export { getLegacyVisibility }; diff --git a/packages/compiler/src/experimental/index.ts b/packages/compiler/src/experimental/index.ts index a7b3a243e6..e6f4938564 100644 --- a/packages/compiler/src/experimental/index.ts +++ b/packages/compiler/src/experimental/index.ts @@ -1,5 +1,7 @@ export { MutableType as unsafe_MutableType, + mutateSubgraph as unsafe_mutateSubgraph, + mutateSubgraphWithNamespace as unsafe_mutateSubgraphWithNamespace, Mutator as unsafe_Mutator, MutatorFilterFn as unsafe_MutatorFilterFn, MutatorFlow as unsafe_MutatorFlow, @@ -7,9 +9,13 @@ export { MutatorRecord as unsafe_MutatorRecord, MutatorReplaceFn as unsafe_MutatorReplaceFn, MutatorWithNamespace as unsafe_MutatorWithNamespace, - mutateSubgraph as unsafe_mutateSubgraph, - mutateSubgraphWithNamespace as unsafe_mutateSubgraphWithNamespace, } from "./mutators.js"; export { Realm as unsafe_Realm } from "./realm.js"; -export { unsafe_useStateMap, unsafe_useStateSet } from "./state-accessor.js"; export { $ as unsafe_$ } from "./typekit/index.js"; + +import { useStateMap, useStateSet } from "../utils/state-accessor.js"; + +/** @deprecated use `useStateMap` from `@typespec/compiler/utils` instead */ +export const unsafe_useStateMap = useStateMap; +/** @deprecated use `useStateSet` from `@typespec/compiler/utils` instead */ +export const unsafe_useStateSet = useStateSet; diff --git a/packages/compiler/src/lib/decorators.ts b/packages/compiler/src/lib/decorators.ts index 40f15e7867..b886ca14dc 100644 --- a/packages/compiler/src/lib/decorators.ts +++ b/packages/compiler/src/lib/decorators.ts @@ -98,8 +98,8 @@ import { UnionVariant, Value, } from "../core/types.js"; +import { useStateMap, useStateSet } from "../utils/index.js"; import { setKey } from "./key.js"; -import { useStateMap, useStateSet } from "./utils.js"; export { $encodedName, resolveEncodedName } from "./encoded-names.js"; export { serializeValueAsJson } from "./examples.js"; @@ -121,11 +121,11 @@ function replaceTemplatedStringFromProperties(formatString: string, sourceObject }); } -export function createStateSymbol(name: string) { +function createStateSymbol(name: string) { return Symbol.for(`TypeSpec.${name}`); } -const [getSummary, setSummary] = useStateMap("summary"); +const [getSummary, setSummary] = useStateMap(createStateSymbol("summary")); /** * @summary attaches a documentation string. It is typically used to give a short, single-line * description, and can be used in combination with or instead of @doc. @@ -326,7 +326,7 @@ function validateTargetingAString( // -- @error decorator ---------------------- -const [getErrorState, setErrorState] = useStateSet("error"); +const [getErrorState, setErrorState] = useStateSet(createStateSymbol("error")); /** * `@error` decorator marks a model as an error type. * Any derived models (using extends) will also be seen as error types. @@ -355,7 +355,7 @@ export function isErrorModel(program: Program, target: Type): boolean { // -- @format decorator --------------------- -const [getFormat, setFormat] = useStateMap("format"); +const [getFormat, setFormat] = useStateMap(createStateSymbol("format")); /** * `@format` - specify the data format hint for a string type @@ -395,7 +395,9 @@ export const $format: FormatDecorator = ( export { getFormat }; // -- @pattern decorator --------------------- -const [getPatternData, setPatternData] = useStateMap("patternValues"); +const [getPatternData, setPatternData] = useStateMap( + createStateSymbol("patternValues"), +); export interface PatternData { readonly pattern: string; @@ -656,7 +658,7 @@ export const $maxValueExclusive: MaxValueExclusiveDecorator = ( }; // -- @secret decorator --------------------- -const [isSecret, markSecret] = useStateSet("secretTypes"); +const [isSecret, markSecret] = useStateSet(createStateSymbol("secretTypes")); /** * Mark a string as a secret value that should be treated carefully to avoid exposure @@ -690,7 +692,9 @@ export interface EncodeData { type: Scalar; } -const [getEncode, setEncodeData] = useStateMap("encode"); +const [getEncode, setEncodeData] = useStateMap( + createStateSymbol("encode"), +); export const $encode: EncodeDecorator = ( context: DecoratorContext, target: Scalar | ModelProperty, @@ -893,7 +897,7 @@ export const $withoutDefaultValues: WithoutDefaultValuesDecorator = ( // -- @tag decorator --------------------- -const [getTagsState, setTags] = useStateMap("tagProperties"); +const [getTagsState, setTags] = useStateMap(createStateSymbol("tagProperties")); // Set a tag on an operation, interface, or namespace. There can be multiple tags on an // operation, interface, or namespace. @@ -943,7 +947,9 @@ export function getAllTags( // -- @friendlyName decorator --------------------- -const [getFriendlyName, setFriendlyName] = useStateMap("friendlyNames"); +const [getFriendlyName, setFriendlyName] = useStateMap( + createStateSymbol("friendlyNames"), +); export const $friendlyName: FriendlyNameDecorator = ( context: DecoratorContext, target: Type, @@ -981,7 +987,7 @@ export const $friendlyName: FriendlyNameDecorator = ( export { getFriendlyName }; -const [getKnownValues, setKnownValues] = useStateMap("knownValues"); +const [getKnownValues, setKnownValues] = useStateMap(createStateSymbol("knownValues")); /** * `@knownValues` marks a string type with an enum that contains all known values @@ -1100,9 +1106,11 @@ export function getDeprecated(program: Program, type: Type): string | undefined return getDeprecationDetails(program, type)?.message; } -const [getOverloads, setOverloads] = useStateMap("overloadedByKey"); +const [getOverloads, setOverloads] = useStateMap( + createStateSymbol("overloadedByKey"), +); const [getOverloadedOperation, setOverloadBase] = useStateMap( - "overloadsOperation", + createStateSymbol("overloadsOperation"), ); /** @@ -1293,7 +1301,7 @@ export interface OpExample extends ExampleOptions { const [getExamplesState, setExamples] = useStateMap< Model | Scalar | Enum | Union | ModelProperty | UnionVariant, Example[] ->("examples"); +>(createStateSymbol("examples")); export const $example: ExampleDecorator = ( context: DecoratorContext, target: Model | Scalar | Enum | Union | ModelProperty | UnionVariant, @@ -1334,7 +1342,9 @@ export function getExamples( return getExamplesState(program, target) ?? []; } -const [getOpExamplesState, setOpExamples] = useStateMap("opExamples"); +const [getOpExamplesState, setOpExamples] = useStateMap( + createStateSymbol("opExamples"), +); export const $opExample: OpExampleDecorator = ( context: DecoratorContext, target: Operation, diff --git a/packages/compiler/src/lib/encoded-names.ts b/packages/compiler/src/lib/encoded-names.ts index 6156ed72ee..612e68bede 100644 --- a/packages/compiler/src/lib/encoded-names.ts +++ b/packages/compiler/src/lib/encoded-names.ts @@ -2,13 +2,16 @@ import { reportDiagnostic } from "../core/messages.js"; import { parseMimeType } from "../core/mime-type.js"; import type { Program } from "../core/program.js"; import type { DecoratorContext, Enum, Model, Type, Union } from "../core/types.js"; -import { DuplicateTracker } from "../utils/index.js"; -import { useStateMap } from "./utils.js"; +import { DuplicateTracker, useStateMap } from "../utils/index.js"; + +function createStateSymbol(name: string) { + return Symbol.for(`TypeSpec.${name}`); +} const [getEncodedNamesMap, setEncodedNamesMap, getEncodedNamesStateMap] = useStateMap< Type, Map ->("encodedName"); +>(createStateSymbol("encodedName")); export function $encodedName( context: DecoratorContext, diff --git a/packages/compiler/src/lib/key.ts b/packages/compiler/src/lib/key.ts index 2e7ba1a96a..eb7f8a76d7 100644 --- a/packages/compiler/src/lib/key.ts +++ b/packages/compiler/src/lib/key.ts @@ -1,8 +1,12 @@ import { Program } from "../core/index.js"; import { ModelProperty, Type } from "../core/types.js"; -import { useStateMap } from "./utils.js"; +import { useStateMap } from "../utils/index.js"; -const [getKey, setKey] = useStateMap("key"); +function createStateSymbol(name: string) { + return Symbol.for(`TypeSpec.${name}`); +} + +const [getKey, setKey] = useStateMap(createStateSymbol("key")); export function isKey(program: Program, property: ModelProperty) { return getKey(program, property) !== undefined; diff --git a/packages/compiler/src/lib/paging.ts b/packages/compiler/src/lib/paging.ts index a462ca4b01..e4ca7a079b 100644 --- a/packages/compiler/src/lib/paging.ts +++ b/packages/compiler/src/lib/paging.ts @@ -26,9 +26,8 @@ import type { Operation, Type, } from "../core/types.js"; -import { DuplicateTracker } from "../utils/duplicate-tracker.js"; +import { DuplicateTracker, useStateSet } from "../utils/index.js"; import { isNumericType, isStringType } from "./decorators.js"; -import { useStateSet } from "./utils.js"; export const [ /** @@ -342,11 +341,15 @@ function validatePagingOperation(program: Program, op: Operation) { program.reportDiagnostics(diagnostics); } +function createStateSymbol(name: string) { + return Symbol.for(`TypeSpec.${name}`); +} + function createMarkerDecorator( key: string, validate?: (...args: Parameters) => boolean, ) { - const [isLink, markLink] = useStateSet[1]>(key); + const [isLink, markLink] = useStateSet[1]>(createStateSymbol(key)); const decorator = (...args: Parameters) => { if (validate && !validate(...args)) { return; diff --git a/packages/compiler/src/lib/service.ts b/packages/compiler/src/lib/service.ts index 36bad68430..c4b781b037 100644 --- a/packages/compiler/src/lib/service.ts +++ b/packages/compiler/src/lib/service.ts @@ -4,7 +4,7 @@ import { Type, getTypeName, reportDeprecated } from "../core/index.js"; import { reportDiagnostic } from "../core/messages.js"; import type { Program } from "../core/program.js"; import { DecoratorContext, Namespace } from "../core/types.js"; -import { useStateMap } from "./utils.js"; +import { useStateMap } from "../utils/index.js"; export interface ServiceDetails { title?: string; diff --git a/packages/compiler/src/lib/utils.ts b/packages/compiler/src/lib/utils.ts index 215a456f5f..46625f7b76 100644 --- a/packages/compiler/src/lib/utils.ts +++ b/packages/compiler/src/lib/utils.ts @@ -1,17 +1,4 @@ -import type { Model, ModelProperty, Type } from "../core/types.js"; -import { unsafe_useStateMap, unsafe_useStateSet } from "../experimental/state-accessor.js"; - -function createStateSymbol(name: string) { - return Symbol.for(`TypeSpec.${name}`); -} - -export function useStateMap(key: string | symbol) { - return unsafe_useStateMap(typeof key === "string" ? createStateSymbol(key) : key); -} - -export function useStateSet(key: string | symbol) { - return unsafe_useStateSet(typeof key === "string" ? createStateSymbol(key) : key); -} +import type { Model, ModelProperty } from "../core/types.js"; /** * Filters the properties of a model by removing them from the model instance if diff --git a/packages/compiler/src/lib/visibility.ts b/packages/compiler/src/lib/visibility.ts index 811b4e87bd..7cb7478e9b 100644 --- a/packages/compiler/src/lib/visibility.ts +++ b/packages/compiler/src/lib/visibility.ts @@ -50,11 +50,16 @@ import { normalizeVisibilityToLegacyLifecycleString, } from "../core/visibility/lifecycle.js"; import { isMutableType, mutateSubgraph, Mutator, MutatorFlow } from "../experimental/mutators.js"; +import { useStateMap } from "../utils/index.js"; import { isKey } from "./key.js"; -import { filterModelPropertiesInPlace, useStateMap } from "./utils.js"; +import { filterModelPropertiesInPlace } from "./utils.js"; // #region Legacy Visibility Utilities +function createStateSymbol(name: string) { + return Symbol.for(`TypeSpec.${name}`); +} + /** * Takes a list of visibilities that possibly include both legacy visibility * strings and visibility class members, and returns two lists containing only @@ -136,7 +141,7 @@ interface OperationVisibilityConfig { const [getOperationVisibilityConfigRaw, setOperationVisibilityConfigRaw] = useStateMap< Operation, OperationVisibilityConfig ->("operationVisibilityConfig"); +>(createStateSymbol("operationVisibilityConfig")); function getOperationVisibilityConfig( program: Program, diff --git a/packages/compiler/src/utils/index.ts b/packages/compiler/src/utils/index.ts index 8cec1d47b0..2af3b409d3 100644 --- a/packages/compiler/src/utils/index.ts +++ b/packages/compiler/src/utils/index.ts @@ -4,3 +4,4 @@ // --------------------------------------- export { DuplicateTracker } from "./duplicate-tracker.js"; export { Queue, TwoLevelMap, createRekeyableMap, deepClone, deepEquals } from "./misc.js"; +export { useStateMap, useStateSet } from "./state-accessor.js"; diff --git a/packages/compiler/src/experimental/state-accessor.ts b/packages/compiler/src/utils/state-accessor.ts similarity index 84% rename from packages/compiler/src/experimental/state-accessor.ts rename to packages/compiler/src/utils/state-accessor.ts index 7ae586342f..7f7ddbe996 100644 --- a/packages/compiler/src/experimental/state-accessor.ts +++ b/packages/compiler/src/utils/state-accessor.ts @@ -5,8 +5,7 @@ type StateMapGetter = (program: Program, type: K) => V | unde type StateMapSetter = (program: Program, type: K, value: V) => void; type StateMapMapGetter = (program: Program) => Map; -/** @experimental */ -export function unsafe_useStateMap( +export function useStateMap( key: symbol, ): [StateMapGetter, StateMapSetter, StateMapMapGetter] { const getter = (program: Program, target: K) => program.stateMap(key).get(target); @@ -19,10 +18,7 @@ export function unsafe_useStateMap( type StateSetGetter = (program: Program, type: K) => boolean; type StateSetSetter = (program: Program, type: K) => void; -/** @experimental */ -export function unsafe_useStateSet( - key: symbol, -): [StateSetGetter, StateSetSetter] { +export function useStateSet(key: symbol): [StateSetGetter, StateSetSetter] { const getter = (program: Program, target: K) => program.stateSet(key).has(target); const setter = (program: Program, target: K) => program.stateSet(key).add(target); diff --git a/packages/events/src/decorators.ts b/packages/events/src/decorators.ts index 1a2e7c6146..834b707ddf 100644 --- a/packages/events/src/decorators.ts +++ b/packages/events/src/decorators.ts @@ -1,5 +1,5 @@ import { type ModelProperty, type Union, type UnionVariant } from "@typespec/compiler"; -import { unsafe_useStateMap, unsafe_useStateSet } from "@typespec/compiler/experimental"; +import { useStateMap, useStateSet } from "@typespec/compiler/utils"; import type { ContentTypeDecorator, DataDecorator, @@ -7,7 +7,7 @@ import type { } from "../generated-defs/TypeSpec.Events.js"; import { EventsStateKeys } from "./lib.js"; -const [isEvents, setEvents] = unsafe_useStateSet(EventsStateKeys.events); +const [isEvents, setEvents] = useStateSet(EventsStateKeys.events); export const $eventsDecorator: EventsDecorator = (context, target) => { setEvents(context.program, target); @@ -15,7 +15,7 @@ export const $eventsDecorator: EventsDecorator = (context, target) => { export { isEvents }; -const [getContentType, setContentType] = unsafe_useStateMap( +const [getContentType, setContentType] = useStateMap( EventsStateKeys.contentType, ); @@ -25,7 +25,7 @@ export const $contentTypeDecorator: ContentTypeDecorator = (context, target, con export { getContentType }; -const [isEventData, setEventData] = unsafe_useStateSet(EventsStateKeys.data); +const [isEventData, setEventData] = useStateSet(EventsStateKeys.data); export const $dataDecorator: DataDecorator = (context, target) => { setEventData(context.program, target); diff --git a/packages/json-schema/src/decorators.ts b/packages/json-schema/src/decorators.ts index df2c93bf65..72c97d654e 100644 --- a/packages/json-schema/src/decorators.ts +++ b/packages/json-schema/src/decorators.ts @@ -12,7 +12,7 @@ import { typespecTypeToJson, type Union, } from "@typespec/compiler"; -import { unsafe_useStateMap, unsafe_useStateSet } from "@typespec/compiler/experimental"; +import { useStateMap, useStateSet } from "@typespec/compiler/utils"; import type { ValidatesRawJsonDecorator } from "../generated-defs/TypeSpec.JsonSchema.Private.js"; import type { ContainsDecorator, @@ -43,7 +43,7 @@ export const [ /** Check if the given type is annotated with `@jsonSchema` */ getJsonSchema, markJsonSchema, -] = unsafe_useStateSet(JsonSchemaStateKeys.JsonSchema); +] = useStateSet(JsonSchemaStateKeys.JsonSchema); /** {@inheritdoc JsonSchemaDecorator} */ export const $jsonSchema: JsonSchemaDecorator = ( context: DecoratorContext, @@ -135,7 +135,7 @@ export const [ /** Check if given type is annotated with `@oneOf` decorator */ isOneOf, markOneOf, -] = unsafe_useStateSet(JsonSchemaStateKeys["JsonSchema.oneOf"]); +] = useStateSet(JsonSchemaStateKeys["JsonSchema.oneOf"]); /** {@inheritdoc OneOfDecorator} */ export const $oneOf: OneOfDecorator = (context: DecoratorContext, target: Type) => { @@ -170,7 +170,7 @@ export const [ /** Check if the given array is annotated with `@uniqueItems` decorator */ getUniqueItems, setUniqueItems, -] = unsafe_useStateMap(JsonSchemaStateKeys["JsonSchema.uniqueItems"]); +] = useStateMap(JsonSchemaStateKeys["JsonSchema.uniqueItems"]); /** {@inheritdoc UniqueItemsDecorator} */ export const $uniqueItems: UniqueItemsDecorator = (context: DecoratorContext, target: Type) => setUniqueItems(context.program, target, true); @@ -226,7 +226,7 @@ export const [ /** Get prefix items set with `@prefixItems` decorator */ getPrefixItems, setPrefixItems, -] = unsafe_useStateMap(JsonSchemaStateKeys["JsonSchema.prefixItems"]); +] = useStateMap(JsonSchemaStateKeys["JsonSchema.prefixItems"]); /** {@inheritdoc PrefixItemsDecorator} */ export const $prefixItems: PrefixItemsDecorator = ( @@ -247,10 +247,9 @@ export interface ExtensionRecord { value: Type | unknown; } -const [getExtensionsInternal, _, getExtensionsStateMap] = unsafe_useStateMap< - Type, - ExtensionRecord[] ->(JsonSchemaStateKeys["JsonSchema.extension"]); +const [getExtensionsInternal, _, getExtensionsStateMap] = useStateMap( + JsonSchemaStateKeys["JsonSchema.extension"], +); /** {@inheritdoc ExtensionDecorator} */ export const $extension: ExtensionDecorator = ( context: DecoratorContext, diff --git a/packages/json-schema/src/utils.ts b/packages/json-schema/src/utils.ts index 463957f4c6..192651ad91 100644 --- a/packages/json-schema/src/utils.ts +++ b/packages/json-schema/src/utils.ts @@ -1,11 +1,11 @@ import type { DecoratorFunction, Type } from "@typespec/compiler"; -import { unsafe_useStateMap } from "@typespec/compiler/experimental"; +import { useStateMap } from "@typespec/compiler/utils"; export function createDataDecorator< T extends DecoratorFunction, Target extends Type = Parameters[1], >(key: symbol, validate?: (...args: Parameters) => boolean) { - const [getData, setData] = unsafe_useStateMap[2]>(key); + const [getData, setData] = useStateMap[2]>(key); const decorator = (...args: Parameters) => { if (validate && !validate(...args)) { return; diff --git a/packages/openapi/src/decorators.ts b/packages/openapi/src/decorators.ts index f7adbf1caf..f979c9500a 100644 --- a/packages/openapi/src/decorators.ts +++ b/packages/openapi/src/decorators.ts @@ -12,7 +12,7 @@ import { typespecTypeToJson, TypeSpecValue, } from "@typespec/compiler"; -import { unsafe_useStateMap } from "@typespec/compiler/experimental"; +import { useStateMap } from "@typespec/compiler/utils"; import { setStatusCode } from "@typespec/http"; import { DefaultResponseDecorator, @@ -243,10 +243,9 @@ function omitUndefined>(data: T): T { } /** Get TagsMetadata set with `@tagMetadata` decorator */ -const [getTagsMetadata, setTagsMetadata] = unsafe_useStateMap< - Type, - { [name: string]: TagMetadata } ->(OpenAPIKeys.tagsMetadata); +const [getTagsMetadata, setTagsMetadata] = useStateMap( + OpenAPIKeys.tagsMetadata, +); /** * Decorator to add metadata to a tag associated with a namespace. diff --git a/packages/sse/src/decorators.ts b/packages/sse/src/decorators.ts index 566e1df5b6..e42acfeb79 100644 --- a/packages/sse/src/decorators.ts +++ b/packages/sse/src/decorators.ts @@ -1,11 +1,9 @@ import type { UnionVariant } from "@typespec/compiler"; -import { unsafe_useStateSet } from "@typespec/compiler/experimental"; +import { useStateSet } from "@typespec/compiler/utils"; import type { TerminalEventDecorator } from "../generated-defs/TypeSpec.SSE.js"; import { SSEStateKeys } from "./lib.js"; -const [isTerminalEvent, setTerminalEvent] = unsafe_useStateSet( - SSEStateKeys.terminalEvent, -); +const [isTerminalEvent, setTerminalEvent] = useStateSet(SSEStateKeys.terminalEvent); export const $terminalEventDecorator: TerminalEventDecorator = (context, target) => { setTerminalEvent(context.program, target); diff --git a/packages/streams/src/decorators.ts b/packages/streams/src/decorators.ts index bf5608ece6..203493a913 100644 --- a/packages/streams/src/decorators.ts +++ b/packages/streams/src/decorators.ts @@ -1,9 +1,9 @@ import type { Model, Program, Type } from "@typespec/compiler"; -import { unsafe_useStateMap } from "@typespec/compiler/experimental"; +import { useStateMap } from "@typespec/compiler/utils"; import type { StreamOfDecorator } from "../generated-defs/TypeSpec.Streams.js"; import { StreamStateKeys } from "./lib.js"; -const [getStreamOf, setStreamOf] = unsafe_useStateMap(StreamStateKeys.streamOf); +const [getStreamOf, setStreamOf] = useStateMap(StreamStateKeys.streamOf); export const $streamOfDecorator: StreamOfDecorator = (context, target, type) => { setStreamOf(context.program, target, type);