Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lazy load @parcel/watcher and fallback to chokidar #2414

Merged
merged 5 commits into from
Nov 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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

Expand Down
50 changes: 25 additions & 25 deletions lib/src/io/js.dart
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,31 @@ Future<Stream<WatchEvent>> 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<WatchEvent>? 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<ParcelWatcherEvent> 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<WatchEvent>(onCancel: () {
subscription.unsubscribe();
}))
.stream;
} else {
var watcher = chokidar.watch(path, ChokidarOptions(usePolling: poll));
watcher
..on(
'add',
Expand Down Expand Up @@ -286,28 +309,5 @@ Future<Stream<WatchEvent>> watchDir(String path, {bool poll = false}) async {
}));

return completer.future;
} else {
var subscription = await ParcelWatcher.subscribeFuture(path,
(Object? error, List<ParcelWatcherEvent> 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<WatchEvent>(onCancel: () {
subscription.unsubscribe();
}))
.stream;
}
}
51 changes: 28 additions & 23 deletions lib/src/js/parcel_watcher.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,48 @@
// 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;
}

/// 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<ParcelWatcherSubscription> subscribeFuture(String path,
@JS()
extension type ParcelWatcher(JSObject _) implements JSObject {
@JS('subscribe')
external JSPromise<ParcelWatcherSubscription> _subscribe(
String path, JSFunction callback);
Future<ParcelWatcherSubscription> subscribe(String path,
void Function(Object? error, List<ParcelWatcherEvent>) callback) =>
promiseToFuture(
subscribe(path, allowInterop((Object? error, List<dynamic> events) {
callback(error, events.cast<ParcelWatcherEvent>());
})));
_subscribe(
path,
(JSObject? error, JSArray<ParcelWatcherEvent> events) {
callback(error, events.toDart);
}.toJS)
.toDart;

external static Promise getEventsSince(String path, String snapshotPath);
static Future<List<ParcelWatcherEvent>> getEventsSinceFuture(
String path, String snapshotPath) async {
List<dynamic> events =
await promiseToFuture(getEventsSince(path, snapshotPath));
return events.cast<ParcelWatcherEvent>();
}
@JS('getEventsSince')
external JSPromise<JSArray<ParcelWatcherEvent>> _getEventsSince(
String path, String snapshotPath);
Future<List<ParcelWatcherEvent>> getEventsSince(
String path, String snapshotPath) async =>
(await _getEventsSince(path, snapshotPath).toDart).toDart;

external static Promise writeSnapshot(String path, String snapshotPath);
static Future<void> writeSnapshotFuture(String path, String snapshotPath) =>
promiseToFuture(writeSnapshot(path, snapshotPath));
@JS('writeSnapshot')
external JSPromise<JSAny> _writeSnapshot(String path, String snapshotPath);
Future<void> writeSnapshot(String path, String snapshotPath) =>
_writeSnapshot(path, snapshotPath).toDart;
}

@JS('parcel_watcher')
external ParcelWatcher? get parcelWatcher;
2 changes: 1 addition & 1 deletion lib/src/parse/parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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].
Expand Down
2 changes: 1 addition & 1 deletion lib/src/visitor/async_evaluate.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
4 changes: 2 additions & 2 deletions lib/src/visitor/evaluate.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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;
}
Expand Down
4 changes: 3 additions & 1 deletion package/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion pkg/sass-parser/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## 0.4.3-dev
## 0.4.3

* Add support for parsing the `@while` rule.

Expand Down
2 changes: 1 addition & 1 deletion pkg/sass-parser/package.json
Original file line number Diff line number Diff line change
@@ -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.",
Expand Down
2 changes: 1 addition & 1 deletion pkg/sass_api/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## 14.1.2-dev
## 14.1.2

* No user-visible changes.

Expand Down
4 changes: 2 additions & 2 deletions pkg/sass_api/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions pubspec.yaml
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -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
Expand Down
3 changes: 2 additions & 1 deletion tool/grind.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ void main(List<String> 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),
Expand Down