@fable-org/fable-library-ts 1.4.3 → 1.6.0

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.
package/Async.ts CHANGED
@@ -1,40 +1,33 @@
1
1
  import { OperationCanceledError, Trampoline } from "./AsyncBuilder.js";
2
2
  import { Continuation, Continuations } from "./AsyncBuilder.js";
3
- import { CancellationToken } from "./AsyncBuilder.js";
4
- import { IAsync } from "./AsyncBuilder.js";
5
- import { IAsyncContext } from "./AsyncBuilder.js";
6
- import { protectedCont } from "./AsyncBuilder.js";
7
- import { protectedBind } from "./AsyncBuilder.js";
8
- import { protectedReturn } from "./AsyncBuilder.js";
3
+ import { Async, IAsyncContext, CancellationToken } from "./AsyncBuilder.js";
4
+ import { protectedCont, protectedBind, protectedReturn } from "./AsyncBuilder.js";
9
5
  import { FSharpChoice$2_$union, Choice_makeChoice1Of2, Choice_makeChoice2Of2 } from "./Choice.js";
10
6
  import { TimeoutException } from "./SystemException.js";
11
7
 
12
- // Implemented just for type references
13
- export class Async<_T> { }
14
-
15
8
  function emptyContinuation<T>(_x: T) {
16
9
  // NOP
17
10
  }
18
11
 
19
12
  // see AsyncBuilder.Delay
20
- function delay<T>(generator: () => IAsync<T>) {
13
+ function delay<T>(generator: () => Async<T>) {
21
14
  return protectedCont((ctx: IAsyncContext<T>) => generator()(ctx));
22
15
  }
23
16
 
24
17
  // MakeAsync: body:(AsyncActivation<'T> -> AsyncReturn) -> Async<'T>
25
- export function makeAsync<T>(body: IAsync<T>) {
18
+ export function makeAsync<T>(body: Async<T>) {
26
19
  return body;
27
20
  }
28
21
  // Invoke: computation: Async<'T> -> ctxt:AsyncActivation<'T> -> AsyncReturn
29
- export function invoke<T>(computation: IAsync<T>, ctx: IAsyncContext<T>) {
22
+ export function invoke<T>(computation: Async<T>, ctx: IAsyncContext<T>) {
30
23
  return computation(ctx);
31
24
  }
32
25
  // CallThenInvoke: ctxt:AsyncActivation<'T> -> result1:'U -> part2:('U -> Async<'T>) -> AsyncReturn
33
- export function callThenInvoke<T, U>(ctx: IAsyncContext<T>, result1: U, part2: (x: U) => IAsync<T>) {
26
+ export function callThenInvoke<T, U>(ctx: IAsyncContext<T>, result1: U, part2: (x: U) => Async<T>) {
34
27
  return part2(result1)(ctx);
35
28
  }
36
29
  // Bind: ctxt:AsyncActivation<'T> -> part1:Async<'U> -> part2:('U -> Async<'T>) -> AsyncReturn
37
- export function bind<T, U>(ctx: IAsyncContext<T>, part1: IAsync<U>, part2: (x: U) => IAsync<T>) {
30
+ export function bind<T, U>(ctx: IAsyncContext<T>, part1: Async<U>, part2: (x: U) => Async<T>) {
38
31
  return protectedBind(part1, part2)(ctx);
39
32
  }
40
33
 
@@ -64,7 +57,7 @@ export function throwIfCancellationRequested(token: CancellationToken) {
64
57
  }
65
58
  }
66
59
 
67
- function throwAfter(millisecondsDueTime: number) : IAsync<void> {
60
+ function throwAfter(millisecondsDueTime: number): Async<void> {
68
61
  return protectedCont((ctx: IAsyncContext<void>) => {
69
62
  let tokenId: number;
70
63
  const timeoutId = setTimeout(() => {
@@ -78,7 +71,7 @@ function throwAfter(millisecondsDueTime: number) : IAsync<void> {
78
71
  });
79
72
  }
80
73
 
81
- export function startChild<T>(computation: IAsync<T>, ms?: number): IAsync<IAsync<T>> {
74
+ export function startChild<T>(computation: Async<T>, ms?: number): Async<Async<T>> {
82
75
  if (ms) {
83
76
  const computationWithTimeout = protectedBind(
84
77
  parallel2(
@@ -110,7 +103,7 @@ export function cancellationToken() {
110
103
 
111
104
  export const defaultCancellationToken = new CancellationToken();
112
105
 
113
- export function catchAsync<T>(work: IAsync<T>) {
106
+ export function catchAsync<T>(work: Async<T>) {
114
107
  return protectedCont((ctx: IAsyncContext<FSharpChoice$2_$union<T, Error>>) => {
115
108
  work({
116
109
  onSuccess: (x) => ctx.onSuccess(Choice_makeChoice1Of2(x)),
@@ -127,21 +120,21 @@ export function fromContinuations<T>(f: (conts: Continuations<T>) => void) {
127
120
  f([ctx.onSuccess, ctx.onError, ctx.onCancel]));
128
121
  }
129
122
 
130
- export function ignore<T>(computation: IAsync<T>) {
123
+ export function ignore<T>(computation: Async<T>) {
131
124
  return protectedBind(computation, (_x) => protectedReturn(void 0));
132
125
  }
133
126
 
134
- export function parallel<T>(computations: Iterable<IAsync<T>>) {
127
+ export function parallel<T>(computations: Iterable<Async<T>>) {
135
128
  return delay(() => awaitPromise(Promise.all(Array.from(computations, (w) => startAsPromise(w)))));
136
129
  }
137
130
 
138
- function parallel2<T, U>(a: IAsync<T>, b: IAsync<U>): IAsync<[T, U]> {
139
- return delay(() => awaitPromise(Promise.all([ startAsPromise(a), startAsPromise(b) ])));
131
+ function parallel2<T, U>(a: Async<T>, b: Async<U>): Async<[T, U]> {
132
+ return delay(() => awaitPromise(Promise.all([startAsPromise(a), startAsPromise(b)])));
140
133
  }
141
134
 
142
- export function sequential<T>(computations: Iterable<IAsync<T>>) {
135
+ export function sequential<T>(computations: Iterable<Async<T>>) {
143
136
 
144
- function _sequential<T>(computations: Iterable<IAsync<T>>): Promise<T[]> {
137
+ function _sequential<T>(computations: Iterable<Async<T>>): Promise<T[]> {
145
138
  let pr: Promise<T[]> = Promise.resolve([]);
146
139
  for (const c of computations) {
147
140
  pr = pr.then(results => startAsPromise(c).then(r => results.concat([r])))
@@ -170,16 +163,16 @@ export function runSynchronously(): never {
170
163
  throw new Error("Asynchronous code cannot be run synchronously in JS");
171
164
  }
172
165
 
173
- export function start<T>(computation: IAsync<T>, cancellationToken?: CancellationToken) {
166
+ export function start<T>(computation: Async<T>, cancellationToken?: CancellationToken) {
174
167
  return startWithContinuations(computation, cancellationToken);
175
168
  }
176
169
 
177
- export function startImmediate<T>(computation: IAsync<T>, cancellationToken?: CancellationToken) {
170
+ export function startImmediate<T>(computation: Async<T>, cancellationToken?: CancellationToken) {
178
171
  return start(computation, cancellationToken);
179
172
  }
180
173
 
181
174
  export function startWithContinuations<T>(
182
- computation: IAsync<T>,
175
+ computation: Async<T>,
183
176
  continuation?: Continuation<T> | CancellationToken,
184
177
  exceptionContinuation?: Continuation<any>,
185
178
  cancellationContinuation?: Continuation<any>,
@@ -198,10 +191,8 @@ export function startWithContinuations<T>(
198
191
  });
199
192
  }
200
193
 
201
- export function startAsPromise<T>(computation: IAsync<T>, cancellationToken?: CancellationToken) {
194
+ export function startAsPromise<T>(computation: Async<T>, cancellationToken?: CancellationToken) {
202
195
  return new Promise((resolve: Continuation<T>, reject: Continuation<any>) =>
203
196
  startWithContinuations(computation, resolve, reject, reject,
204
197
  cancellationToken ? cancellationToken : defaultCancellationToken));
205
198
  }
206
-
207
- export default Async;
package/AsyncBuilder.ts CHANGED
@@ -86,9 +86,9 @@ export interface IAsyncContext<T> {
86
86
  trampoline: Trampoline;
87
87
  }
88
88
 
89
- export type IAsync<T> = (x: IAsyncContext<T>) => void;
89
+ export type Async<T> = (x: IAsyncContext<T>) => void;
90
90
 
91
- export function protectedCont<T>(f: IAsync<T>) {
91
+ export function protectedCont<T>(f: Async<T>) {
92
92
  return (ctx: IAsyncContext<T>) => {
93
93
  if (ctx.cancelToken.isCancelled) {
94
94
  ctx.onCancel(new OperationCanceledError());
@@ -110,7 +110,7 @@ export function protectedCont<T>(f: IAsync<T>) {
110
110
  };
111
111
  }
112
112
 
113
- export function protectedBind<T, U>(computation: IAsync<T>, binder: (x: T) => IAsync<U>) {
113
+ export function protectedBind<T, U>(computation: Async<T>, binder: (x: T) => Async<U>) {
114
114
  return protectedCont((ctx: IAsyncContext<U>) => {
115
115
  computation({
116
116
  onSuccess: (x: T) => {
@@ -133,19 +133,19 @@ export function protectedReturn<T>(value: T) {
133
133
  }
134
134
 
135
135
  export class AsyncBuilder {
136
- public Bind<T, U>(computation: IAsync<T>, binder: (x: T) => IAsync<U>) {
136
+ public Bind<T, U>(computation: Async<T>, binder: (x: T) => Async<U>) {
137
137
  return protectedBind(computation, binder);
138
138
  }
139
139
 
140
- public Combine<T>(computation1: IAsync<void>, computation2: IAsync<T>) {
140
+ public Combine<T>(computation1: Async<void>, computation2: Async<T>) {
141
141
  return this.Bind(computation1, () => computation2);
142
142
  }
143
143
 
144
- public Delay<T>(generator: () => IAsync<T>) {
144
+ public Delay<T>(generator: () => Async<T>) {
145
145
  return protectedCont((ctx: IAsyncContext<T>) => generator()(ctx));
146
146
  }
147
147
 
148
- public For<T>(sequence: Iterable<T>, body: (x: T) => IAsync<void>) {
148
+ public For<T>(sequence: Iterable<T>, body: (x: T) => Async<void>) {
149
149
  const iter = sequence[Symbol.iterator]();
150
150
  let cur = iter.next();
151
151
  return this.While(() => !cur.done, this.Delay(() => {
@@ -155,15 +155,15 @@ export class AsyncBuilder {
155
155
  }));
156
156
  }
157
157
 
158
- public Return<T>(value?: T) {
158
+ public Return<T>(value: T) {
159
159
  return protectedReturn(value);
160
160
  }
161
161
 
162
- public ReturnFrom<T>(computation: IAsync<T>) {
162
+ public ReturnFrom<T>(computation: Async<T>) {
163
163
  return computation;
164
164
  }
165
165
 
166
- public TryFinally<T>(computation: IAsync<T>, compensation: () => void) {
166
+ public TryFinally<T>(computation: Async<T>, compensation: () => void) {
167
167
  return protectedCont((ctx: IAsyncContext<T>) => {
168
168
  computation({
169
169
  onSuccess: (x: T) => {
@@ -184,7 +184,7 @@ export class AsyncBuilder {
184
184
  });
185
185
  }
186
186
 
187
- public TryWith<T>(computation: IAsync<T>, catchHandler: (e: any) => IAsync<T>) {
187
+ public TryWith<T>(computation: Async<T>, catchHandler: (e: any) => Async<T>) {
188
188
  return protectedCont((ctx: IAsyncContext<T>) => {
189
189
  computation({
190
190
  onSuccess: ctx.onSuccess,
@@ -202,11 +202,11 @@ export class AsyncBuilder {
202
202
  });
203
203
  }
204
204
 
205
- public Using<T extends IDisposable, U>(resource: T, binder: (x: T) => IAsync<U>) {
205
+ public Using<T extends IDisposable, U>(resource: T, binder: (x: T) => Async<U>) {
206
206
  return this.TryFinally(binder(resource), () => resource.Dispose());
207
207
  }
208
208
 
209
- public While(guard: () => boolean, computation: IAsync<void>): IAsync<void> {
209
+ public While(guard: () => boolean, computation: Async<void>): Async<void> {
210
210
  if (guard()) {
211
211
  return this.Bind(computation, () => this.While(guard, computation));
212
212
  } else {
package/CHANGELOG.md CHANGED
@@ -7,6 +7,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## Unreleased
9
9
 
10
+ ## 1.6.0 - 2024-10-02
11
+
12
+ ### Removed
13
+
14
+ * Remove `Async` (from `Async.ts`) class (by @MangelMaxime)
15
+
16
+ ### Changed
17
+
18
+ * Renamed `IAsync` to `Async` in `AsyncBuilder.ts` (#3906) (by @ncave)
19
+
20
+ ## 1.5.0 - 2024-09-19
21
+
22
+ ### Added
23
+
24
+ * [JS/TS] Add support for `OrdinalIgnoreCase` overload for `String.EndsWith` (#3892) (by @goswinr)
25
+ * [JS/TS] Add `uri.Port`, `uri.IsDefaultPort` (by @MangelMaxime)
26
+
27
+ ### Fixed
28
+
29
+ * [JS/TS] Fix escaping of `{` and `}` in FormattableString (#3890) (by @roboz0r)
30
+ * [JS/TS] Fix `uri.Host` to return the host name without the port (by @MangelMaxime)
31
+ * [JS/TS] Fix TypeScript compilation by resolving type of `jsOptions` (#3894) (by @ManngelMaxime)
32
+
10
33
  ## 1.4.3 - 2024-09-04
11
34
 
12
35
  * [JS/TS] Fixed Decimal comparisons (#3884) (by @ncave)
@@ -1,7 +1,7 @@
1
1
  import { defaultCancellationToken } from "./Async.js";
2
2
  import { fromContinuations } from "./Async.js";
3
3
  import { startImmediate } from "./Async.js";
4
- import { IAsync } from "./AsyncBuilder.js";
4
+ import { Async } from "./AsyncBuilder.js";
5
5
  import { Continuation, Continuations } from "./AsyncBuilder.js";
6
6
  import { CancellationToken } from "./AsyncBuilder.js";
7
7
 
@@ -41,7 +41,7 @@ class MailboxQueue<Msg> {
41
41
  }
42
42
  }
43
43
 
44
- export type MailboxBody<Msg> = (m: MailboxProcessor<Msg>) => IAsync<void>;
44
+ export type MailboxBody<Msg> = (m: MailboxProcessor<Msg>) => Async<void>;
45
45
 
46
46
  export interface AsyncReplyChannel<Reply> {
47
47
  reply: (r: Reply) => void;
package/String.ts CHANGED
@@ -64,12 +64,25 @@ export function compareTo(x: string, y: string) {
64
64
  }
65
65
 
66
66
  export function startsWith(str: string, pattern: string, ic: number) {
67
+ if (ic === StringComparison.Ordinal) { // to avoid substring allocation
68
+ return str.startsWith(pattern);
69
+ }
67
70
  if (str.length >= pattern.length) {
68
71
  return cmp(str.substr(0, pattern.length), pattern, ic) === 0;
69
72
  }
70
73
  return false;
71
74
  }
72
75
 
76
+ export function endsWith(str: string, pattern: string, ic: number) {
77
+ if (ic === StringComparison.Ordinal) { // to avoid substring allocation
78
+ return str.endsWith(pattern);
79
+ }
80
+ if (str.length >= pattern.length) {
81
+ return cmp(str.substr(str.length - pattern.length, pattern.length), pattern, ic) === 0;
82
+ }
83
+ return false;
84
+ }
85
+
73
86
  export function indexOfAny(str: string, anyOf: string[], ...args: number[]) {
74
87
  if (str == null || str === "") {
75
88
  return -1;
@@ -87,7 +100,7 @@ export function indexOfAny(str: string, anyOf: string[], ...args: number[]) {
87
100
  }
88
101
  const endIndex = startIndex + length
89
102
  const anyOfAsStr = "".concat.apply("", anyOf);
90
- for (let i=startIndex; i<endIndex; i++) {
103
+ for (let i = startIndex; i < endIndex; i++) {
91
104
  if (anyOfAsStr.indexOf(str[i]) > -1) {
92
105
  return i;
93
106
  }
@@ -374,10 +387,6 @@ export function format(str: string | object, ...args: any[]) {
374
387
  });
375
388
  }
376
389
 
377
- export function endsWith(str: string, search: string) {
378
- const idx = str.lastIndexOf(search);
379
- return idx >= 0 && idx === str.length - search.length;
380
- }
381
390
 
382
391
  export function initialize(n: number, f: (i: number) => string) {
383
392
  if (n < 0) {
@@ -587,7 +596,11 @@ export function fmtWith(fmts: string[]) {
587
596
  }
588
597
 
589
598
  export function getFormat(s: FormattableString) {
599
+ const strs = s.strs.map((value) => value.replace(/{/g, '{{').replace(/}/g, '}}'));
600
+
590
601
  return s.fmts
591
- ? s.strs.reduce((acc, newPart, index) => acc + `{${String(index - 1) + s.fmts![index - 1]}}` + newPart)
592
- : s.strs.reduce((acc, newPart, index) => acc + `{${index - 1}}` + newPart);
602
+ ? strs
603
+ .reduce((acc, newPart, index) => acc + `{${String(index - 1) + s.fmts![index - 1]}}` + newPart)
604
+ : strs
605
+ .reduce((acc, newPart, index) => acc + `{${index - 1}}` + newPart);
593
606
  }
package/Uri.ts CHANGED
@@ -177,7 +177,13 @@ export class Uri {
177
177
  }
178
178
 
179
179
  get host() {
180
- return this.asUrl().host;
180
+ const host = this.asUrl().host;
181
+
182
+ if (host.includes(":")) {
183
+ return host.split(":")[0];
184
+ } else {
185
+ return host;
186
+ }
181
187
  }
182
188
 
183
189
  get absolutePath() {
@@ -188,6 +194,20 @@ export class Uri {
188
194
  return this.asUrl().search;
189
195
  }
190
196
 
197
+ get isDefaultPort() {
198
+ return this.port === 80;
199
+ }
200
+
201
+ get port() {
202
+ const port = this.asUrl().port;
203
+
204
+ if (port === "") {
205
+ return 80;
206
+ } else {
207
+ return parseInt(port);
208
+ }
209
+ }
210
+
191
211
  get pathAndQuery() {
192
212
  const url = this.asUrl();
193
213
  return url.pathname + url.search;
package/Util.ts CHANGED
@@ -588,8 +588,8 @@ export function createObj(fields: Iterable<[string, any]>) {
588
588
  return obj;
589
589
  }
590
590
 
591
- export function jsOptions(mutator: (x: object) => void): object {
592
- const opts = {};
591
+ export function jsOptions<T>(mutator: (x: T) => void): T {
592
+ const opts = {} as T;
593
593
  mutator(opts);
594
594
  return opts;
595
595
  }
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "private": false,
4
4
  "type": "module",
5
5
  "name": "@fable-org/fable-library-ts",
6
- "version": "1.4.3",
6
+ "version": "1.6.0",
7
7
  "description": "Core library used by F# projects compiled with fable.io",
8
8
  "author": "Fable Contributors",
9
9
  "license": "MIT",