diff --git a/CHANGELOG.md b/CHANGELOG.md index 232bfdd9d..98816c1aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ -## 1.80.6-dev +## 1.80.6 -* No user-visible changes. +### Command-Line Interface + +* Make `@parcel/watcher` an optional dependency so this can still be installed + on operating systems where it's unavailable. ## 1.80.5 diff --git a/lib/src/io/js.dart b/lib/src/io/js.dart index e8b2e7722..ce730d142 100644 --- a/lib/src/io/js.dart +++ b/lib/src/io/js.dart @@ -257,8 +257,31 @@ Future> watchDir(String path, {bool poll = false}) async { // Don't assign the controller until after the ready event fires. Otherwise, // Chokidar will give us a bunch of add events for files that already exist. StreamController? controller; - if (poll) { - var watcher = chokidar.watch(path, ChokidarOptions(usePolling: true)); + if (parcelWatcher case var parcel? when !poll) { + var subscription = await parcel.subscribe(path, + (Object? error, List events) { + if (error != null) { + controller?.addError(error); + } else { + for (var event in events) { + switch (event.type) { + case 'create': + controller?.add(WatchEvent(ChangeType.ADD, event.path)); + case 'update': + controller?.add(WatchEvent(ChangeType.MODIFY, event.path)); + case 'delete': + controller?.add(WatchEvent(ChangeType.REMOVE, event.path)); + } + } + } + }); + + return (controller = StreamController(onCancel: () { + subscription.unsubscribe(); + })) + .stream; + } else { + var watcher = chokidar.watch(path, ChokidarOptions(usePolling: poll)); watcher ..on( 'add', @@ -286,28 +309,5 @@ Future> watchDir(String path, {bool poll = false}) async { })); return completer.future; - } else { - var subscription = await ParcelWatcher.subscribeFuture(path, - (Object? error, List events) { - if (error != null) { - controller?.addError(error); - } else { - for (var event in events) { - switch (event.type) { - case 'create': - controller?.add(WatchEvent(ChangeType.ADD, event.path)); - case 'update': - controller?.add(WatchEvent(ChangeType.MODIFY, event.path)); - case 'delete': - controller?.add(WatchEvent(ChangeType.REMOVE, event.path)); - } - } - } - }); - - return (controller = StreamController(onCancel: () { - subscription.unsubscribe(); - })) - .stream; } } diff --git a/lib/src/js/parcel_watcher.dart b/lib/src/js/parcel_watcher.dart index 1cf698a23..4d1720bdd 100644 --- a/lib/src/js/parcel_watcher.dart +++ b/lib/src/js/parcel_watcher.dart @@ -2,17 +2,15 @@ // MIT-style license that can be found in the LICENSE file or at // https://opensource.org/licenses/MIT. -import 'package:js/js.dart'; -import 'package:node_interop/js.dart'; -import 'package:node_interop/util.dart'; +import 'dart:js_interop'; @JS() -class ParcelWatcherSubscription { +extension type ParcelWatcherSubscription(JSObject _) implements JSObject { external void unsubscribe(); } @JS() -class ParcelWatcherEvent { +extension type ParcelWatcherEvent(JSObject _) implements JSObject { external String get type; external String get path; } @@ -20,25 +18,32 @@ class ParcelWatcherEvent { /// The @parcel/watcher module. /// /// See [the docs on npm](https://www.npmjs.com/package/@parcel/watcher). -@JS('parcel_watcher') -class ParcelWatcher { - external static Promise subscribe(String path, Function callback); - static Future subscribeFuture(String path, +@JS() +extension type ParcelWatcher(JSObject _) implements JSObject { + @JS('subscribe') + external JSPromise _subscribe( + String path, JSFunction callback); + Future subscribe(String path, void Function(Object? error, List) callback) => - promiseToFuture( - subscribe(path, allowInterop((Object? error, List events) { - callback(error, events.cast()); - }))); + _subscribe( + path, + (JSObject? error, JSArray events) { + callback(error, events.toDart); + }.toJS) + .toDart; - external static Promise getEventsSince(String path, String snapshotPath); - static Future> getEventsSinceFuture( - String path, String snapshotPath) async { - List events = - await promiseToFuture(getEventsSince(path, snapshotPath)); - return events.cast(); - } + @JS('getEventsSince') + external JSPromise> _getEventsSince( + String path, String snapshotPath); + Future> getEventsSince( + String path, String snapshotPath) async => + (await _getEventsSince(path, snapshotPath).toDart).toDart; - external static Promise writeSnapshot(String path, String snapshotPath); - static Future writeSnapshotFuture(String path, String snapshotPath) => - promiseToFuture(writeSnapshot(path, snapshotPath)); + @JS('writeSnapshot') + external JSPromise _writeSnapshot(String path, String snapshotPath); + Future writeSnapshot(String path, String snapshotPath) => + _writeSnapshot(path, snapshotPath).toDart; } + +@JS('parcel_watcher') +external ParcelWatcher? get parcelWatcher; diff --git a/lib/src/parse/parser.dart b/lib/src/parse/parser.dart index 4c4d6ba5e..19ef3971c 100644 --- a/lib/src/parse/parser.dart +++ b/lib/src/parse/parser.dart @@ -651,7 +651,7 @@ class Parser { var span = scanner.spanFrom(state); return _interpolationMap == null ? span - : LazyFileSpan(() => _interpolationMap!.mapSpan(span)); + : LazyFileSpan(() => _interpolationMap.mapSpan(span)); } /// Throws an error associated with [span]. diff --git a/lib/src/visitor/async_evaluate.dart b/lib/src/visitor/async_evaluate.dart index 4dc806e67..aba5cee7c 100644 --- a/lib/src/visitor/async_evaluate.dart +++ b/lib/src/visitor/async_evaluate.dart @@ -1812,7 +1812,7 @@ final class _EvaluateVisitor if (result != null) { isDependency = _inDependency; } else { - result = await _nodeImporter!.loadAsync(originalUrl, previous, forImport); + result = await _nodeImporter.loadAsync(originalUrl, previous, forImport); if (result == null) return null; isDependency = true; } diff --git a/lib/src/visitor/evaluate.dart b/lib/src/visitor/evaluate.dart index e06601361..f9990c828 100644 --- a/lib/src/visitor/evaluate.dart +++ b/lib/src/visitor/evaluate.dart @@ -5,7 +5,7 @@ // DO NOT EDIT. This file was generated from async_evaluate.dart. // See tool/grind/synchronize.dart for details. // -// Checksum: 396c8f169d95c601598b8c3be1f4b948ca22effa +// Checksum: 3986f5db33dd220dcd971a39e8587ca4e52d9a3f // // ignore_for_file: unused_import @@ -1808,7 +1808,7 @@ final class _EvaluateVisitor if (result != null) { isDependency = _inDependency; } else { - result = _nodeImporter!.load(originalUrl, previous, forImport); + result = _nodeImporter.load(originalUrl, previous, forImport); if (result == null) return null; isDependency = true; } diff --git a/package/package.json b/package/package.json index 881e3351c..a2c4fb510 100644 --- a/package/package.json +++ b/package/package.json @@ -17,11 +17,13 @@ "node": ">=14.0.0" }, "dependencies": { - "@parcel/watcher": "^2.4.1", "chokidar": "^4.0.0", "immutable": "^4.0.0", "source-map-js": ">=0.6.2 <2.0.0" }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" + }, "keywords": [ "style", "scss", diff --git a/pkg/sass-parser/CHANGELOG.md b/pkg/sass-parser/CHANGELOG.md index 318bf6151..8af6f962c 100644 --- a/pkg/sass-parser/CHANGELOG.md +++ b/pkg/sass-parser/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.4.3-dev +## 0.4.3 * Add support for parsing the `@while` rule. diff --git a/pkg/sass-parser/package.json b/pkg/sass-parser/package.json index 2ad8cedba..9b5fc6fa9 100644 --- a/pkg/sass-parser/package.json +++ b/pkg/sass-parser/package.json @@ -1,6 +1,6 @@ { "name": "sass-parser", - "version": "0.4.3-dev", + "version": "0.4.3", "description": "A PostCSS-compatible wrapper of the official Sass parser", "repository": "sass/sass", "author": "Google Inc.", diff --git a/pkg/sass_api/CHANGELOG.md b/pkg/sass_api/CHANGELOG.md index 79055abd8..8d2a119ac 100644 --- a/pkg/sass_api/CHANGELOG.md +++ b/pkg/sass_api/CHANGELOG.md @@ -1,4 +1,4 @@ -## 14.1.2-dev +## 14.1.2 * No user-visible changes. diff --git a/pkg/sass_api/pubspec.yaml b/pkg/sass_api/pubspec.yaml index e51f9c0da..8bddb43bf 100644 --- a/pkg/sass_api/pubspec.yaml +++ b/pkg/sass_api/pubspec.yaml @@ -2,12 +2,12 @@ name: sass_api # Note: Every time we add a new Sass AST node, we need to bump the *major* # version because it's a breaking change for anyone who's implementing the # visitor interface(s). -version: 14.1.2-dev +version: 14.1.2 description: Additional APIs for Dart Sass. homepage: https://github.com/sass/dart-sass environment: - sdk: ">=3.0.0 <4.0.0" + sdk: ">=3.3.0 <4.0.0" dependencies: sass: 1.80.6 diff --git a/pubspec.yaml b/pubspec.yaml index bca441faa..6e148ca9f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: sass -version: 1.80.6-dev +version: 1.80.6 description: A Sass implementation in Dart. homepage: https://github.com/sass/dart-sass @@ -8,13 +8,13 @@ executables: sass: sass environment: - sdk: ">=3.0.0 <4.0.0" + sdk: ">=3.3.0 <4.0.0" dependencies: args: ^2.0.0 async: ^2.5.0 charcode: ^1.2.0 - cli_pkg: ^2.8.0 + cli_pkg: ^2.11.0 cli_repl: ^0.2.1 collection: ^1.16.0 http: ^1.1.0 diff --git a/tool/grind.dart b/tool/grind.dart index cf64cc52e..6f2acc9db 100644 --- a/tool/grind.dart +++ b/tool/grind.dart @@ -35,7 +35,8 @@ void main(List args) { pkg.homebrewFormula.value = "Formula/sass.rb"; pkg.homebrewEditFormula.value = _updateHomebrewLanguageRevision; pkg.jsRequires.value = [ - pkg.JSRequire("@parcel/watcher", target: pkg.JSRequireTarget.cli), + pkg.JSRequire("@parcel/watcher", + target: pkg.JSRequireTarget.cli, lazy: true, optional: true), pkg.JSRequire("immutable", target: pkg.JSRequireTarget.all), pkg.JSRequire("chokidar", target: pkg.JSRequireTarget.cli), pkg.JSRequire("readline", target: pkg.JSRequireTarget.cli),