@danielx/civet 0.5.33 → 0.5.35

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/README.md CHANGED
@@ -64,170 +64,13 @@ createCompilerHost := (options: CompilerOptions, moduleSearchLocations : string[
64
64
  fileCache[fileName]
65
65
  ```
66
66
 
67
- Things Kept from CoffeeScript
67
+ Overview
68
68
  ---
69
69
 
70
- - `is` `===`
71
- - `or`, `or=` → `||`, `||=`
72
- - `and`, `and=` → `&&`, `&&=`
73
- - `a %% b` → `(a % b + b) % b`
74
- - `loop` → `while(true)`
75
- - `unless exp` → `if(!exp)`
76
- - `until condition` → `while(!condition)`
77
- - Object literal syntax
78
- ```coffee
79
- x =
80
- a: 1
81
- b: 2
82
- c:
83
- x: "pretty"
84
- y: "cool"
85
- ```
86
- - Optional semi-colons
87
- - Indentation based block syntax
88
- - OptionalChain shorthand for index and function application: `a?[b]` → `a?.[b]`, `a?(b)` → `a?.(b)`
89
- - `?=` null-coalescing assignment shorthand
90
- - `@` `this` shorthand: `@` → `this`, `@id` → `this.id`, `{@id} → {id: this.id}`
91
- - Prototype shorthand: `X::` → `X.prototype`, `X::a` → `X.prototype.a`
92
- - Class static shorthand `@`
93
- - Chained comparisons: `a < b < c` → `a < b && b < c`
94
- - Postfix `if/unless/while/until/for`
95
- - Block Strings `"""` / `'''`
96
- - `#{exp}` interpolation in `"""` strings
97
- - `when` inside `switch` automatically breaks
98
- - Multiple `,` separated `case`/`when` expressions
99
- - `else` → `default` in `switch`
100
- - Range literals `[0...10]`, `[a..b]`, `[x - 2 .. x + 2]`
101
- - Array slices `list[0...2]` → `list.slice(0, 2)`
102
- - Slice assignment `numbers[3..6] = [-3, -4, -5, -6]` → `numbers.splice(3, 4, ...[-3, -4, -5, -6])`
103
- - Implicit returns
104
- - Late assignment `x + y = z` → `x + (y = z)`
105
- - Braceless inline objects `x = coolStory: true`
106
- - Simplified number method calls `1.toFixed()` → `1..toFixed()`
107
- - `if`/`switch`/`for`/`loop`/`while`/`throw` expressions
108
- - Destructuring object assignment doesn't require being wrapped in parens at the statement level `{a, b} = c` → `({a, b} = c)`
109
- - Prefix or postfix rest/splats `[...a]`, `x = [a...]`
110
- - RestProperty in any position `{a, ...b, c} = d` → `{a, c, ...b} = d`
111
- - RestElement/RestParameter in any position `(first, ...midle, last) ->` → `function(first, ...middle) { let [last] = middle.splice(-1)}`
112
- - `///` Heregexp
113
- - With some [changes](#things-changed-from-coffeescript).
114
- - JSX
115
-
116
- Things Removed from CoffeeScript
117
- ---
70
+ Civet is essentially a tasteful superset of TypeScript.
118
71
 
119
- Most of these can be enabled by adding a [`"civet coffeeCompat"` directive prologue](#coffeescript-compatibility) to the top of your file.
120
- The goal is to provide a very high level of compatibility with existing CoffeeScript code while offering a fine grained migration path to modern
121
- Civet.
122
-
123
- - Implicit `var` declarations (use `"civet coffeeCompat"` or `"civet autoVar"`)
124
- - `on/yes/off/no` (use `true/false`, `"civet coffeeCompat"`, or `"civet coffeeBooleans"` to add them back)
125
- - `not` (use `!`, `"civet coffeeCompat"`, or `"civet coffeeNot"`)
126
- - `not instanceof` (use `!(a instanceof b)`, `"civet coffeeCompat"`, or `"civet coffeeNot"`)
127
- - `not of` use (`"civet coffeeCompat"`, or `"civet coffeeNot"`)
128
- - NOTE: CoffeeScript `not` precedence is dubious. `not a < b` should be equivalent to `!(a < b)` but it is in fact `!a < b`
129
- - `do` keyword (replaced with JS `do`, invoke using existing `(-> ...)()` syntax, `"civet coffeeCompat"`, or `"civet coffeeDo"`)
130
- - `for from` (use JS `for of`, `"civet coffeeCompat"`, or `"civet coffeeForLoops"`)
131
- - `for own of` (use JS `for in` and check manually, switch to `Map#keys/values/entries`, or use `Object.create(null)`, or `"civet coffeeCompat"`, or `"civet coffeeForLoops"`)
132
- - `for ... when <condition>` (use `continue if exp` inside loop, `"civet coffeeCompat"`, or `"civet coffeeForLoops"`)
133
- - `a ? b` (use `a ?? b`, though it doesn't check for undeclared variables; `"civet coffeeCompat"`, or `"civet coffeeBinaryExistential"` enables `a ? b` at the cost of losing JS ternary operator)
134
- - `a of b` (use `a in b` as in JS, or `"civet coffeeCompat"`, or `"civet coffeeOf"`)
135
- - Backtick embedded JS (replaced by template literals)
136
- - Will add later
137
- - Conditional assignment `a?[x] = 3` → `a ? a[x] = 3 : undefined`
138
- - Multiple slice assignment `otherNumbers[0...] = numbers[3..6] = [-3, -4, -5, -6]`
139
-
140
- Things Changed from CoffeeScript
141
- ---
142
-
143
- - `==` → `==` rather than `===` (unless you specify `"civet coffeeCompat"` or `"civet coffeeEq"`)
144
- - `!=` → `!=` rather than `!==` (unless you specify `"civet coffeeCompat"` or `"civet coffeeEq"`)
145
- - `is not` → `!==`
146
- (unless you specify `"civet coffeeCompat"` or `"civet coffeeNot"`),
147
- instead of `isnt`
148
- (unless you specify `"civet coffeeCompat"` or `"civet coffeeIsnt"`)
149
- - `for in` and `for of` are no longer swapped and become their JS equivalents (unless you specify `"civet coffeeCompat"` or `"civet CoffeeOf"`)
150
- - `a is in b` → `b.indexOf(a) >= 0` and
151
- `a is not in b` → `b.indexOf(a) < 0` instead of `a in b` and `a not in b`;
152
- `a in b` remains `a in b` as in JS, and `a not in b` → `!(a in b)`
153
- (unless you specify `"civet coffeeCompat"` or `"civet coffeeOf"`)
154
- - `x?.y` now compiles to `x?.y` rather than the `if typeof x !== 'undefined' && x !== null` if check
155
- - Existential `x?` → `(x != null)` no longer checks for undeclared variables.
156
- - `x?()` → `x?.()` instead of `if (typeof x === 'function') { x() }`
157
- - Functions don't implicitly return the last value if there's a semicolon
158
- at the end: `-> x` returns `x` but `-> x;` does not
159
- - Backtick embedded JS has been replaced with JS template literals.
160
- - No longer allowing multiple postfix `if/unless` on the same line (use `&&` or `and` to combine conditions).
161
- - `#{}` interpolation in `""` strings only when `"civet coffeeCompat"` or `"civet coffeeInterpolation"`
162
- - Expanded chained comparisons to work on more operators `a in b instanceof C` → `a in b && b instanceof C`
163
- - Postfix iteration/conditionals always wrap the statement [#5431](https://github.com/jashkenas/coffeescript/issues/5431):
164
- `try x() if y` → `if (y) try x()`
165
- - Civet tries to keep the transpiled output verbatim as much as possible.
166
- In Coffee `(x)` → `x;` but in Civet `(x)` → `(x)`. Spacing and comments are also preserved as much as possible.
167
- - Heregex / re.X
168
- - Stay closer to the [Python spec](https://docs.python.org/3/library/re.html#re.X)
169
- - Allows both kinds of substitutions `#{..}`, `${..}`.
170
- - Also allows both kinds of single line comments `//`, `#`.
171
- - Keeps non-newline whitespace inside of character classes.
172
- - Doesn't require escaping `#` after space inside of character classes.
173
- - `#` is always the start of a comment outside of character classes regardless of leading space (CoffeeScript treats
174
- `\s+#` as comment starts inside and outside of character classes).
175
- - Might later add a compat flag to get more CoffeeScript compatibility.
176
- - Might also later add a compat flag to only use ES interpolations and comments inside Heregexes.
177
-
178
- Things Added that CoffeeScript didn't
179
- ---
72
+ ### Implementations of New and Proposed ES Features
180
73
 
181
- - TypeScript Compatibility
182
- - Auto-rewrite `.[mc]ts` → `.[mc]js` in imports (workaround for: https://github.com/microsoft/TypeScript/issues/37582)
183
- - Function annotations
184
- - `namespace`
185
- - `interface`
186
- - TypeParameters
187
- - `!` non-null assertions
188
- - `:=` readonly class field initializer
189
- ```typescript
190
- class A
191
- x := 3
192
- ```
193
- ```typescript
194
- class A {
195
- readonly x = 3
196
- }
197
- ```
198
- - JS Compatibility
199
- - `var`, `let`, `const`
200
- - JS Comment Syntax `//` and `/* */`
201
- - `function` keyword
202
- - Braced Blocks (as an alternative to indentation)
203
- - `f?.(x)` function application and `a?.[x]` index OptionalChain longhand
204
- - `a ? b : c` ConditionalExpression
205
- - `case` statement
206
- - `do`, `do { ... } until condition`
207
- - Method definitions `foo(args) ...` in objects/classes
208
- - `get`/`set` method definitions
209
- - Private identifiers `#id`
210
- - Convenience for ES6+ Features
211
- - Const assignment shorthand: `a := b` → `const a = b`, `{a, b} := c` → `const {a, b} = c`
212
- - Let assignment shorthand (experimental): `a .= b` or `a ::= b` → `let a = b`
213
- - Typed versions of above: `a: number .= 5` → `let a: number = 5`
214
- (but note that `a: number = 5` is the object literal `{a: (number = 5)}`).
215
- - `@#id` → `this.#id` shorthand for private identifiers
216
- - `import` shorthand: `x from ./x` → `import x from "./x"`
217
- - Dynamic `import` shorthand: `import './x'` not at top level
218
- (e.g. `await import './x'` or inside a function) →
219
- `import('./x')`
220
- - `export` shorthand: `export x, y` → `export {x, y}`
221
- - Triple backtick Template Strings remove leading indentation for clarity
222
- - Class constructor shorthand `@( ... )`
223
- - ClassStaticBlock `@ { ... }`
224
- - `<` as `extends` shorthand
225
- - Short function block syntax like [Ruby symbol to proc](https://ruby-doc.org/core-3.1.2/Symbol.html#method-i-to_proc), [Crystal](https://crystal-lang.org/reference/1.6/syntax_and_semantics/blocks_and_procs.html#short-one-parameter-syntax), [Elm record access](https://elm-lang.org/docs/records#access)
226
- - Access: `x.map &.name` → `x.map(a => a.name)`
227
- - Nested access + slices: `x.map &.profile?.name[0...3]` → `x.map(a => a.profile?.name.slice(0, 3))`
228
- - Function call: `x.map &.callback a, b` → `x.map($ => $.callback(a, b))`
229
- - Unary operators: `x.map !!&` → `x.map($ => !!$)`
230
- - Binary operators: `x.map &+1` → `x.map($ => $+1)`
231
74
  - Pipe operator (based on [F# pipes](https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/symbol-and-operator-reference/#function-symbols-and-operators), [Hack pipes](https://docs.hhvm.com/hack/expressions-and-operators/pipe) and the [TC39 proposal](https://github.com/tc39/proposal-pipeline-operator))
232
75
  - `data |> Object.keys |> console.log` equivalent to
233
76
  `console.log(Object.keys(data))`
@@ -235,52 +78,93 @@ Things Added that CoffeeScript didn't
235
78
  to specify how to use left-hand side
236
79
  - `|> await`, `|> yield`, and `|> return` (at end)
237
80
  for wrapping left-hand side with that operation
81
+ - Short function block syntax like [Ruby symbol to proc](https://ruby-doc.org/core-3.1.2/Symbol.html#method-i-to_proc), [Crystal](https://crystal-lang.org/reference/1.6/syntax_and_semantics/blocks_and_procs.html#short-one-parameter-syntax), [Elm record access](https://elm-lang.org/docs/records#access)
82
+ - Access: `x.map &.name` → `x.map(a => a.name)`
83
+ - Nested access + slices: `x.map &.profile?.name[0...3]` → `x.map(a => a.profile?.name.slice(0, 3))`
84
+ - Function call: `x.map &.callback a, b` → `x.map($ => $.callback(a, b))`
85
+ - Unary operators: `x.map !!&` → `x.map($ => !!$)`
86
+ - Binary operators: `x.map &+1` → `x.map($ => $+1)`
238
87
  - Flagging shorthand based on [from LiveScript](https://livescript.net/#literals-objects):
239
88
  `{+debug, -live, !verbose}` → `{debug: true, live: false, verbose: false}`
240
- - JSX enhancements (inspired by [solid-dsl discussions](https://github.com/solidjs-community/solid-dsl/discussions)):
241
- - Indentation: instead of explicitly closing `<tag>`s or `<>`s,
242
- you can indent the children and Civet will close your tags for you
243
- - Multiple adjacent elements and/or fragments get automatically
244
- combined into a fragment.
245
- - Arrow function children do not need to be wrapped in braces
246
- (assuming they are not preceded by text); this is unambiguous because
247
- `>` isn't valid JSX text. For example, `<For> (item) => ...`
248
- (where function body can be indented).
249
- - `#foo` shorthand for `id="foo"`;
250
- also `#"foo bar"`, `` #`foo ${bar}` ``, `#{expr}`
251
- - `.foo` shorthand for `class="foo"` (but must be at least one space after
252
- tag name); also `.foo.bar`, `."foo bar"`, `` .`foo ${bar}` ``, `.{expr}`
253
- - `"civet react"` flag uses `className` instead of `class`
254
- - `+foo` shorthand for `foo={true}`, `-foo`/`!foo` shorthand for `foo={false}`
255
- - Any braced object literal can be used as an attribute:
256
- `{foo}` `foo={foo}`, `{foo: bar}` → `foo={bar}`,
257
- `{...foo}` remains as is; methods and getters/setters work too.
258
- - Attribute `...foo` shorthand for `{...foo}`
259
- - Attribute values without whitespace or suitably wrapped
260
- (parenthesized expressions, strings and template strings,
261
- regular expressions, array literals, braced object literals)
262
- do not need braces:
263
- `foo=bar` `foo={bar}`, `count=count()` → `count={count()}`,
264
- `sum=x+1` → `sum={x+1}`, `list=[1, 2, 3]` → `list={[1, 2, 3]}`
265
- - Attributes can use computed property names:
266
- `[expr]={value}` → `{...{[expr]: value}}`
267
- - `"civet solid"` flag adds correct types for JSX elements and fragments.
268
- Use `"civet solid client"` (default) for client-only code,
269
- `"civet solid server"` for server-only code (SSR only), or
270
- `"civet solid client server"` for isomorphic code that runs on
271
- client and server (SSR + hydration).
272
- - XML comments: `<!-- ... -->` `{/* ... */}`
273
- - CoffeeScript improvements
274
- - Postfix loop `run() loop` → `while(true) run()`
275
- - Character range literals `["a".."z"]`, `['f'..'a']`, `['0'..'9']`
276
- - Shebang line is kept unmodified in output
277
- ```civet
278
- #!./node_modules/.bin/ts-node
279
- console.log "hi"
89
+
90
+
91
+ ### Convenience for ES6+ Features
92
+
93
+ - Const assignment shorthand: `a := b` → `const a = b`, `{a, b} := c` → `const {a, b} = c`
94
+ - Let assignment shorthand: `a .= b` `let a = b`
95
+ - Typed versions of above: `a: number .= 5` `let a: number = 5`
96
+ (but note that `a: number = 5` is the object literal `{a: (number = 5)}`).
97
+ - `@#id` `this.#id` shorthand for private identifiers
98
+ - `import` shorthand: `x from ./x` → `import x from "./x"`
99
+ - Dynamic `import` shorthand: `import './x'` not at top level
100
+ (e.g. `await import './x'` or inside a function)
101
+ `import('./x')`
102
+ - Optional import rename syntax that corresponds to destructuring rename
103
+ `import {x: y} from "./z"` `import {x as y} from "./z"`. You can still
104
+ use `as` to be compatible with existing ES imports.
105
+ - `export` shorthand: `export x, y` → `export {x, y}`
106
+ - Triple backtick Template Strings remove leading indentation for clarity
107
+ - Class constructor shorthand `@( ... )`
108
+ - ClassStaticBlock `@ { ... }`
109
+ - `<` as `extends` shorthand
110
+ - `///` Block RegExp [like Python re.X](https://docs.python.org/3/library/re.html#re.X)
111
+
112
+ ### JSX Enhancements
113
+
114
+ Largely inspired by [solid-dsl discussions](https://github.com/solidjs-community/solid-dsl/discussions)
115
+
116
+ - Indentation: instead of explicitly closing `<tag>`s or `<>`s,
117
+ you can indent the children and Civet will close your tags for you
118
+ - Multiple adjacent elements and/or fragments get automatically
119
+ combined into a fragment.
120
+ - Arrow function children do not need to be wrapped in braces
121
+ (assuming they are not preceded by text); this is unambiguous because
122
+ `>` isn't valid JSX text. For example, `<For> (item) => ...`
123
+ (where function body can be indented).
124
+ - `#foo` shorthand for `id="foo"`;
125
+ also `#"foo bar"`, `` #`foo ${bar}` ``, `#{expr}`
126
+ - `.foo` shorthand for `class="foo"` (but must be at least one space after
127
+ tag name); also `.foo.bar`, `."foo bar"`, `` .`foo ${bar}` ``, `.{expr}`
128
+ - `"civet react"` flag uses `className` instead of `class`
129
+ - `+foo` shorthand for `foo={true}`, `-foo`/`!foo` shorthand for `foo={false}`
130
+ - Any braced object literal can be used as an attribute:
131
+ `{foo}` → `foo={foo}`, `{foo: bar}` → `foo={bar}`,
132
+ `{...foo}` remains as is; methods and getters/setters work too.
133
+ - Attribute `...foo` shorthand for `{...foo}`
134
+ - Attribute values without whitespace or suitably wrapped
135
+ (parenthesized expressions, strings and template strings,
136
+ regular expressions, array literals, braced object literals)
137
+ do not need braces:
138
+ `foo=bar` → `foo={bar}`, `count=count()` → `count={count()}`,
139
+ `sum=x+1` → `sum={x+1}`, `list=[1, 2, 3]` → `list={[1, 2, 3]}`
140
+ - Attributes can use computed property names:
141
+ `[expr]={value}` → `{...{[expr]: value}}`
142
+ - `"civet solid"` flag adds correct types for JSX elements and fragments.
143
+ Use `"civet solid client"` (default) for client-only code,
144
+ `"civet solid server"` for server-only code (SSR only), or
145
+ `"civet solid client server"` for isomorphic code that runs on
146
+ client and server (SSR + hydration).
147
+ - XML comments: `<!-- ... -->` → `{/* ... */}`
148
+
149
+ ### TypeScript Enhancements
150
+
151
+ - Auto-rewrite `.[mc]ts` → `.[mc]js` in imports (workaround for: https://github.com/microsoft/TypeScript/issues/37582)
152
+ - `:=` readonly class field initializer
153
+ ```typescript
154
+ class A
155
+ x := 3
156
+ ```
157
+ ```typescript
158
+ class A {
159
+ readonly x = 3
160
+ }
280
161
  ```
162
+ - Proposal: [Typed Destructuring](https://github.com/DanielXMoore/Civet/discussions/126)
163
+ - Proposal: [Dot Notation for Types](https://github.com/DanielXMoore/Civet/discussions/190)
164
+ - Proposal: [Module Interfaces](https://github.com/DanielXMoore/Civet/discussions/179) https://github.com/microsoft/TypeScript/issues/38511
165
+ - TODO: [Type Declaration Shorthand](https://github.com/DanielXMoore/Civet/issues/176)
281
166
 
282
- Things Changed from ES6
283
- ---
167
+ ### Changes from ES6
284
168
 
285
169
  - Implicit returns, even for multi-statement functions
286
170
  (avoid by specifying a `void` return type, adding a trailing `;` or
@@ -308,38 +192,37 @@ could be a valid property `1.e10` → `1..e10`. The workaround is to add a trail
308
192
  - No whitespace between unary operators and operands. Mandatory whitespace between condition and ternary `?` ex. `x ? a : b` since `x?` is the unary existential operator.
309
193
  - No labels (yet...)
310
194
 
311
- CoffeeScript Compatibility
312
- ---
195
+ ### Scripting Improvements
196
+
197
+ - Shebang line is kept unmodified in output
198
+ ```civet
199
+ #!./node_modules/.bin/ts-node
200
+ console.log "hi"
201
+ ```
313
202
 
314
- Civet provides a compatibility prologue directive that aims to be 97+% compatible with existing CoffeeScript2 code (still a work in progress).
203
+ Comparison to CoffeeScript
204
+ ---
315
205
 
316
- | Configuration | What it enables |
317
- |---------------------|---------------------------------------------------------------------|
318
- | autoVar | declare implicit vars based on assignment to undeclared identifiers |
319
- | coffeeBooleans | `yes`, `no`, `on`, `off` |
320
- | coffeeComment | `# single line comments` |
321
- | coffeeDo | `do ->`, disables ES6 do/while |
322
- | coffeeEq | `==` → `===`, `!=` → `!==` |
323
- | coffeeForLoops | for in, of, from loops behave like they do in CoffeeScript |
324
- | coffeeInterpolation | `"a string with #{myVar}"` |
325
- | coffeeIsnt | `isnt` → `!==` |
326
- | coffeeNot | `not` → `!`, `a not instanceof b` → `!(a instanceof b)`, `a not of b` → `!(a in b)` |
327
- | coffeeOf | `a of b` → `a in b`, `a in b` → `b.indexOf(a) >= 0`, `a not in b` → `b.indexOf(a) < 0` |
328
-
329
- You can use these with `"civet coffeeCompat"` to opt in to all or use them bit by bit with `"civet coffeeComment coffeeEq coffeeInterpolation"`.
330
- Another possibility is to slowly remove them to provide a way to migrate files a little at a time `"civet coffeeCompat -coffeeBooleans -coffeeComment -coffeeEq"`.
331
- Both camel case and hyphens work when specifying options `"civet coffee-compat"`. More options will be added over time until 97+% compatibility is achieved.
206
+ Take a look at this [detailed Civet // CoffeeScript comparision](./notes/Comparison-to-CoffeeScript.md)
332
207
 
333
208
  ECMAScript Compatibility
334
209
  ---
335
210
 
336
- You can also specify `"civet"` prologue directives to increase
211
+ You can specify `"civet"` prologue directives to increase
337
212
  compatibility with ECMAScript/TypeScript:
338
213
 
339
214
  | Configuration | What it enables |
340
215
  |---------------------|---------------------------------------|
341
216
  | -implicit-returns | turn off implicit return of last value in functions |
342
217
 
218
+ Put them at the top of your file:
219
+
220
+ ```
221
+ "civet -implicit-returns"
222
+ ```
223
+
224
+ Your can separate multiple options with spaces.
225
+
343
226
  Other Options
344
227
  ---
345
228
 
@@ -385,7 +268,7 @@ Currently Civet's ESM loader depends on [ts-node](https://www.npmjs.com/package/
385
268
  ],
386
269
  "loader": [
387
270
  "ts-node/esm",
388
- "@danielx/civet/esm.mjs"
271
+ "@danielx/civet/esm"
389
272
  ],
390
273
  ...
391
274
  ...