effect 4.0.0-beta.21 → 4.0.0-beta.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/dist/Array.d.ts +8 -9
  2. package/dist/Array.d.ts.map +1 -1
  3. package/dist/Array.js.map +1 -1
  4. package/dist/Chunk.d.ts +4 -4
  5. package/dist/Chunk.d.ts.map +1 -1
  6. package/dist/Chunk.js.map +1 -1
  7. package/dist/Duration.d.ts +1 -1
  8. package/dist/Duration.d.ts.map +1 -1
  9. package/dist/Duration.js +1 -1
  10. package/dist/Duration.js.map +1 -1
  11. package/dist/Effect.d.ts +2 -2
  12. package/dist/Effect.d.ts.map +1 -1
  13. package/dist/Effect.js.map +1 -1
  14. package/dist/Filter.d.ts +4 -4
  15. package/dist/Filter.d.ts.map +1 -1
  16. package/dist/Filter.js.map +1 -1
  17. package/dist/HashMap.d.ts +3 -3
  18. package/dist/HashMap.d.ts.map +1 -1
  19. package/dist/HashMap.js.map +1 -1
  20. package/dist/Iterable.d.ts +4 -5
  21. package/dist/Iterable.d.ts.map +1 -1
  22. package/dist/Iterable.js.map +1 -1
  23. package/dist/Record.d.ts +4 -5
  24. package/dist/Record.d.ts.map +1 -1
  25. package/dist/Record.js.map +1 -1
  26. package/dist/Runtime.d.ts.map +1 -1
  27. package/dist/Runtime.js +7 -1
  28. package/dist/Runtime.js.map +1 -1
  29. package/dist/SchemaAST.d.ts.map +1 -1
  30. package/dist/SchemaAST.js +4 -0
  31. package/dist/SchemaAST.js.map +1 -1
  32. package/dist/Stream.d.ts +7 -1
  33. package/dist/Stream.d.ts.map +1 -1
  34. package/dist/Stream.js +5 -1
  35. package/dist/Stream.js.map +1 -1
  36. package/dist/Trie.d.ts +3 -3
  37. package/dist/Trie.d.ts.map +1 -1
  38. package/dist/Trie.js.map +1 -1
  39. package/dist/TxHashMap.d.ts +3 -3
  40. package/dist/TxHashMap.d.ts.map +1 -1
  41. package/dist/TxHashMap.js.map +1 -1
  42. package/dist/internal/effect.js +10 -38
  43. package/dist/internal/effect.js.map +1 -1
  44. package/dist/internal/hashMap.js.map +1 -1
  45. package/dist/internal/schema/representation.js +39 -102
  46. package/dist/internal/schema/representation.js.map +1 -1
  47. package/dist/internal/trie.js.map +1 -1
  48. package/dist/unstable/ai/Chat.d.ts +2 -2
  49. package/dist/unstable/ai/Chat.d.ts.map +1 -1
  50. package/dist/unstable/ai/Chat.js +35 -42
  51. package/dist/unstable/ai/Chat.js.map +1 -1
  52. package/dist/unstable/ai/LanguageModel.d.ts.map +1 -1
  53. package/dist/unstable/ai/LanguageModel.js.map +1 -1
  54. package/dist/unstable/ai/Tool.d.ts +1 -1
  55. package/dist/unstable/ai/Tool.d.ts.map +1 -1
  56. package/dist/unstable/httpapi/HttpApiClient.d.ts +55 -0
  57. package/dist/unstable/httpapi/HttpApiClient.d.ts.map +1 -1
  58. package/dist/unstable/httpapi/HttpApiClient.js +37 -0
  59. package/dist/unstable/httpapi/HttpApiClient.js.map +1 -1
  60. package/dist/unstable/httpapi/OpenApi.js +1 -1
  61. package/dist/unstable/httpapi/OpenApi.js.map +1 -1
  62. package/dist/unstable/schema/VariantSchema.d.ts +2 -2
  63. package/dist/unstable/schema/VariantSchema.d.ts.map +1 -1
  64. package/dist/unstable/schema/VariantSchema.js +3 -3
  65. package/dist/unstable/schema/VariantSchema.js.map +1 -1
  66. package/package.json +1 -1
  67. package/src/Array.ts +15 -13
  68. package/src/Chunk.ts +6 -6
  69. package/src/Duration.ts +2 -2
  70. package/src/Effect.ts +4 -2
  71. package/src/Filter.ts +4 -5
  72. package/src/HashMap.ts +3 -3
  73. package/src/Iterable.ts +6 -7
  74. package/src/Record.ts +6 -7
  75. package/src/Runtime.ts +7 -1
  76. package/src/SchemaAST.ts +5 -0
  77. package/src/Stream.ts +12 -3
  78. package/src/Trie.ts +3 -3
  79. package/src/TxHashMap.ts +4 -4
  80. package/src/internal/effect.ts +27 -53
  81. package/src/internal/hashMap.ts +3 -4
  82. package/src/internal/schema/representation.ts +36 -90
  83. package/src/internal/trie.ts +3 -4
  84. package/src/unstable/ai/Chat.ts +36 -51
  85. package/src/unstable/ai/LanguageModel.ts +0 -1
  86. package/src/unstable/ai/Tool.ts +1 -1
  87. package/src/unstable/httpapi/HttpApiClient.ts +82 -1
  88. package/src/unstable/httpapi/OpenApi.ts +1 -1
  89. package/src/unstable/schema/VariantSchema.ts +3 -3
@@ -296,42 +296,8 @@ const encodeHistoryJson = Schema.encodeUnknownEffect(Schema.fromJsonString(Promp
296
296
  // Constructors
297
297
  // =============================================================================
298
298
 
299
- /**
300
- * Creates a new Chat service with empty conversation history.
301
- *
302
- * This is the most common way to start a fresh chat session without
303
- * any initial context or system prompts.
304
- *
305
- * @example
306
- * ```ts
307
- * import { Effect } from "effect"
308
- * import { Chat } from "effect/unstable/ai"
309
- *
310
- * const freshChat = Effect.gen(function*() {
311
- * const chat = yield* Chat.empty
312
- *
313
- * const response = yield* chat.generateText({
314
- * prompt: "Hello! Can you introduce yourself?"
315
- * })
316
- *
317
- * console.log(response.content)
318
- *
319
- * return chat
320
- * })
321
- * ```
322
- *
323
- * @since 4.0.0
324
- * @category constructors
325
- */
326
- export const empty: Effect.Effect<Service> = Effect.gen(function*() {
327
- const history = yield* Ref.make(Prompt.empty)
328
- const services = yield* Effect.services<never>()
329
- const semaphore = yield* Semaphore.make(1)
330
-
331
- const provideContext = <A, E, R>(effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> =>
332
- Effect.updateServices(effect, (existing) => ServiceMap.merge(services, existing))
333
- const provideContextStream = <A, E, R>(stream: Stream.Stream<A, E, R>): Stream.Stream<A, E, R> =>
334
- Stream.updateServices(stream, (existing) => ServiceMap.merge(services, existing))
299
+ const makeUnsafe = (history: Ref.Ref<Prompt.Prompt>) => {
300
+ const semaphore = Semaphore.makeUnsafe(1)
335
301
 
336
302
  return Chat.of({
337
303
  history,
@@ -368,7 +334,6 @@ export const empty: Effect.Effect<Service> = Effect.gen(function*() {
368
334
 
369
335
  return response
370
336
  },
371
- provideContext,
372
337
  semaphore.withPermits(1),
373
338
  (effect) => Effect.withSpan(effect, "Chat.generateText", { captureStackTrace: false })
374
339
  ),
@@ -397,7 +362,6 @@ export const empty: Effect.Effect<Service> = Effect.gen(function*() {
397
362
  semaphore.release(1)
398
363
  )
399
364
  )).pipe(
400
- provideContextStream,
401
365
  Stream.withSpan("Chat.streamText", {
402
366
  captureStackTrace: false
403
367
  })
@@ -418,7 +382,6 @@ export const empty: Effect.Effect<Service> = Effect.gen(function*() {
418
382
 
419
383
  return response
420
384
  },
421
- provideContext,
422
385
  semaphore.withPermits(1),
423
386
  (effect, options) =>
424
387
  Effect.withSpan(effect, "Chat.generateObject", {
@@ -429,7 +392,36 @@ export const empty: Effect.Effect<Service> = Effect.gen(function*() {
429
392
  })
430
393
  )
431
394
  })
432
- })
395
+ }
396
+
397
+ /**
398
+ * Creates a new Chat service with empty conversation history.
399
+ *
400
+ * This is the most common way to start a fresh chat session without
401
+ * any initial context or system prompts.
402
+ *
403
+ * @example
404
+ * ```ts
405
+ * import { Effect } from "effect"
406
+ * import { Chat } from "effect/unstable/ai"
407
+ *
408
+ * const freshChat = Effect.gen(function*() {
409
+ * const chat = yield* Chat.empty
410
+ *
411
+ * const response = yield* chat.generateText({
412
+ * prompt: "Hello! Can you introduce yourself?"
413
+ * })
414
+ *
415
+ * console.log(response.content)
416
+ *
417
+ * return chat
418
+ * })
419
+ * ```
420
+ *
421
+ * @since 4.0.0
422
+ * @category constructors
423
+ */
424
+ export const empty: Effect.Effect<Service> = Effect.sync(() => makeUnsafe(Ref.makeUnsafe(Prompt.empty)))
433
425
 
434
426
  /**
435
427
  * Creates a new Chat service from an initial prompt.
@@ -489,13 +481,8 @@ export const empty: Effect.Effect<Service> = Effect.gen(function*() {
489
481
  * @since 4.0.0
490
482
  * @category constructors
491
483
  */
492
- export const fromPrompt = Effect.fnUntraced(
493
- function*(prompt: Prompt.RawInput) {
494
- const chat = yield* empty
495
- yield* Ref.set(chat.history, Prompt.make(prompt))
496
- return chat
497
- }
498
- )
484
+ export const fromPrompt = (prompt: Prompt.RawInput) =>
485
+ Effect.sync(() => makeUnsafe(Ref.makeUnsafe(Prompt.make(prompt))))
499
486
 
500
487
  /**
501
488
  * Creates a Chat service from previously exported chat data.
@@ -534,8 +521,7 @@ export const fromPrompt = Effect.fnUntraced(
534
521
  */
535
522
  export const fromExport = (data: unknown): Effect.Effect<
536
523
  Service,
537
- Schema.SchemaError,
538
- LanguageModel.LanguageModel
524
+ Schema.SchemaError
539
525
  > => Effect.flatMap(decodeHistory(data), fromPrompt)
540
526
 
541
527
  /**
@@ -576,8 +562,7 @@ export const fromExport = (data: unknown): Effect.Effect<
576
562
  */
577
563
  export const fromJson = (data: string): Effect.Effect<
578
564
  Service,
579
- Schema.SchemaError,
580
- LanguageModel.LanguageModel
565
+ Schema.SchemaError
581
566
  > => Effect.flatMap(decodeHistoryJson(data), fromPrompt)
582
567
 
583
568
  // =============================================================================
@@ -1236,7 +1236,6 @@ export const make: (params: ConstructorParams) => Effect.Effect<Service> = Effec
1236
1236
  const queue = yield* Queue.make<
1237
1237
  Response.StreamPart<Tools>,
1238
1238
  | AiError.AiError
1239
- | AiError.AiErrorReason
1240
1239
  | Cause.Done
1241
1240
  | Schema.SchemaError
1242
1241
  >()
@@ -952,7 +952,7 @@ export type HandlerError<T> = T extends Tool<
952
952
  infer _Name,
953
953
  infer _Config,
954
954
  infer _Requirements
955
- > ? _Config["failureMode"] extends "error" ? _Config["failure"]["Type"] | AiError.AiError | AiError.AiErrorReason
955
+ > ? _Config["failureMode"] extends "error" ? _Config["failure"]["Type"] | AiError.AiError
956
956
  : never
957
957
  : never
958
958
 
@@ -120,6 +120,44 @@ export declare namespace Client {
120
120
  never
121
121
  }
122
122
 
123
+ type ApiGroups<Api extends HttpApi.Any> = Api extends HttpApi.HttpApi<infer _ApiId, infer Groups> ? Groups : never
124
+
125
+ type EndpointId<Endpoint extends HttpApiEndpoint.Any> = Endpoint extends {
126
+ readonly method: infer Method extends HttpMethod.HttpMethod
127
+ readonly path: infer Path extends string
128
+ } ? `${Method} ${Path}`
129
+ : never
130
+
131
+ type EndpointWithId<Endpoints extends HttpApiEndpoint.Any, Id extends string> = Id extends
132
+ `${infer Method extends HttpMethod.HttpMethod} ${infer Path extends string}` ?
133
+ Extract<Endpoints, { readonly method: Method; readonly path: Path }> :
134
+ never
135
+
136
+ type UrlBuilderRequest<Endpoint extends HttpApiEndpoint.Any> = (
137
+ & ([HttpApiEndpoint.Params<Endpoint>["Encoded"]] extends [never] ? {}
138
+ : { readonly params: HttpApiEndpoint.Params<Endpoint>["Encoded"] })
139
+ & ([HttpApiEndpoint.Query<Endpoint>["Encoded"]] extends [never] ? {}
140
+ : { readonly query: HttpApiEndpoint.Query<Endpoint>["Encoded"] })
141
+ ) extends infer Request ? keyof Request extends never ? void | undefined : Request
142
+ : never
143
+
144
+ type UrlBuilderArgs<Endpoint extends HttpApiEndpoint.Any> = [UrlBuilderRequest<Endpoint>] extends [void | undefined] ?
145
+ [request?: UrlBuilderRequest<Endpoint>]
146
+ : [request: UrlBuilderRequest<Endpoint>]
147
+
148
+ /**
149
+ * @since 4.0.0
150
+ * @category models
151
+ */
152
+ export type UrlBuilder<Api extends HttpApi.Any> = <
153
+ const GroupName extends HttpApiGroup.Name<ApiGroups<Api>>,
154
+ const Id extends EndpointId<HttpApiGroup.EndpointsWithName<ApiGroups<Api>, GroupName>>
155
+ >(
156
+ group: GroupName,
157
+ endpoint: Id,
158
+ ...args: UrlBuilderArgs<EndpointWithId<HttpApiGroup.EndpointsWithName<ApiGroups<Api>, GroupName>, Id>>
159
+ ) => string
160
+
123
161
  const makeClient = <ApiId extends string, Groups extends HttpApiGroup.Any, E, R>(
124
162
  api: HttpApi.HttpApi<ApiId, Groups>,
125
163
  options: {
@@ -438,6 +476,49 @@ export const endpoint = <
438
476
  }).pipe(Effect.map(() => client)) as any
439
477
  }
440
478
 
479
+ /**
480
+ * Creates a type-safe URL builder keyed by `${method} ${path}`.
481
+ *
482
+ * @example
483
+ * ```ts
484
+ * import { Schema } from "effect"
485
+ * import { HttpApi, HttpApiClient, HttpApiEndpoint, HttpApiGroup } from "effect/unstable/httpapi"
486
+ *
487
+ * const Api = HttpApi.make("Api").add(
488
+ * HttpApiGroup.make("users").add(
489
+ * HttpApiEndpoint.get("getUser", "/users/:id", {
490
+ * params: { id: Schema.String }
491
+ * })
492
+ * )
493
+ * )
494
+ *
495
+ * const buildUrl = HttpApiClient.urlBuilder<typeof Api>({
496
+ * baseUrl: "https://api.example.com"
497
+ * })
498
+ *
499
+ * buildUrl("users", "GET /users/:id", {
500
+ * params: { id: "123" }
501
+ * })
502
+ * //=> "https://api.example.com/users/123"
503
+ * ```
504
+ * @since 4.0.0
505
+ * @category constructors
506
+ */
507
+ export const urlBuilder = <Api extends HttpApi.Any>(options?: {
508
+ readonly baseUrl?: URL | string | undefined
509
+ }): UrlBuilder<Api> => {
510
+ return ((_: string, endpoint: string, request?: {
511
+ readonly params?: Record<string, string | undefined> | undefined
512
+ readonly query?: UrlParams.Input | undefined
513
+ }) => {
514
+ const path = endpoint.slice(endpoint.indexOf(" ") + 1)
515
+ const withParams = request?.params === undefined ? path : compilePath(path)(request.params)
516
+ const query = request?.query === undefined ? "" : UrlParams.toString(UrlParams.fromInput(request.query))
517
+ const url = query === "" ? withParams : `${withParams}?${query}`
518
+ return options?.baseUrl === undefined ? url : new URL(url, options.baseUrl.toString()).toString()
519
+ }) as UrlBuilder<Api>
520
+ }
521
+
441
522
  // ----------------------------------------------------------------------------
442
523
 
443
524
  const paramsRegExp = /:(\w+)\??/g
@@ -448,7 +529,7 @@ const compilePath = (path: string) => {
448
529
  if (len === 1) {
449
530
  return (_: any) => path
450
531
  }
451
- return (params: Record<string, string>) => {
532
+ return (params: Record<string, string | undefined>) => {
452
533
  let url = segments[0]
453
534
  for (let i = 1; i < len; i++) {
454
535
  if (i % 2 === 0) {
@@ -363,7 +363,7 @@ export function fromApi<Id extends string, Groups extends HttpApiGroup.Any>(
363
363
 
364
364
  function processParameters(schema: Schema.Top | undefined, i: OpenAPISpecParameter["in"]) {
365
365
  if (schema) {
366
- const ast = AST.toEncoded(schema.ast)
366
+ const ast = AST.getLastEncoding(schema.ast)
367
367
  if (AST.isObjects(ast)) {
368
368
  for (const ps of ast.propertySignatures) {
369
369
  op.parameters.push({
@@ -17,7 +17,7 @@ import * as Struct_ from "../../Struct.ts"
17
17
  * @since 4.0.0
18
18
  * @category Type IDs
19
19
  */
20
- export const TypeId = "~effect/unstable/schema/VariantSchema"
20
+ export const TypeId = "~effect/schema/VariantSchema"
21
21
 
22
22
  const cacheSymbol = Symbol.for(`${TypeId}/cache`)
23
23
 
@@ -71,7 +71,7 @@ export declare namespace Struct {
71
71
  }
72
72
  }
73
73
 
74
- const FieldTypeId = "~effect/unstable/schema/VariantSchema/Field"
74
+ const FieldTypeId = "~effect/schema/VariantSchema/Field"
75
75
 
76
76
  /**
77
77
  * @since 4.0.0
@@ -542,7 +542,7 @@ const Union = <Members extends ReadonlyArray<Struct<any>>, Variants extends Read
542
542
  members: Members,
543
543
  variants: Variants
544
544
  ) => {
545
- class VariantUnion extends (Schema.Union(members.filter((member) => Schema.isSchema(member))) as any) {}
545
+ const VariantUnion = Schema.Union(members.filter((member) => Schema.isSchema(member))) as any
546
546
  for (const variant of variants) {
547
547
  Object.defineProperty(VariantUnion, variant, {
548
548
  value: Schema.Union(members.map((member) => extract(member, variant)))