Skip to content

Commit c0af44f

Browse files
committed
Add worker_threads interop file and implementation
Something here is not working 100%, on running render `ParentPort` is null and it should be an object if its on the worker thread.
1 parent 9c8e93f commit c0af44f

File tree

2 files changed

+79
-50
lines changed

2 files changed

+79
-50
lines changed

lib/src/node.dart

Lines changed: 41 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import 'node/render_result.dart';
2828
import 'node/types.dart';
2929
import 'node/value.dart';
3030
import 'node/utils.dart';
31+
import 'node/worker_threads.dart';
3132
import 'parse/scss.dart';
3233
import 'syntax.dart';
3334
import 'value.dart';
@@ -68,56 +69,54 @@ void main() {
6869
/// [render]: https://github.com/sass/node-sass#options
6970
void _render(
7071
RenderOptions options, void callback(JSError error, RenderResult result)) {
71-
if (options.fiber != null) {
72-
options.fiber.call(allowInterop(() {
73-
try {
74-
callback(null, _renderSync(options));
75-
} catch (error) {
76-
callback(error as JSError, null);
77-
}
78-
return null;
79-
})).run();
80-
} else {
81-
_renderAsync(options).then((result) {
82-
callback(null, result);
83-
}, onError: (Object error, StackTrace stackTrace) {
84-
if (error is SassException) {
85-
callback(_wrapException(error), null);
86-
} else {
87-
callback(_newRenderError(error.toString(), status: 3), null);
88-
}
89-
});
90-
}
72+
_renderAsync(options).then((result) {
73+
callback(null, result);
74+
}, onError: (Object error, StackTrace stackTrace) {
75+
if (error is SassException) {
76+
callback(_wrapException(error), null);
77+
} else {
78+
callback(_newRenderError(error.toString(), status: 3), null);
79+
}
80+
});
9181
}
9282

9383
/// Converts Sass to CSS asynchronously.
9484
Future<RenderResult> _renderAsync(RenderOptions options) async {
9585
var start = DateTime.now();
9686
var file = options.file == null ? null : p.absolute(options.file);
9787
CompileResult result;
98-
if (options.data != null) {
99-
result = await compileStringAsync(options.data,
100-
nodeImporter: _parseImporter(options, start),
101-
functions: _parseFunctions(options, asynch: true),
102-
syntax: isTruthy(options.indentedSyntax) ? Syntax.sass : null,
103-
style: _parseOutputStyle(options.outputStyle),
104-
useSpaces: options.indentType != 'tab',
105-
indentWidth: _parseIndentWidth(options.indentWidth),
106-
lineFeed: _parseLineFeed(options.linefeed),
107-
url: options.file == null ? 'stdin' : p.toUri(file).toString(),
108-
sourceMap: _enableSourceMaps(options));
109-
} else if (options.file != null) {
110-
result = await compileAsync(file,
111-
nodeImporter: _parseImporter(options, start),
112-
functions: _parseFunctions(options, asynch: true),
113-
syntax: isTruthy(options.indentedSyntax) ? Syntax.sass : null,
114-
style: _parseOutputStyle(options.outputStyle),
115-
useSpaces: options.indentType != 'tab',
116-
indentWidth: _parseIndentWidth(options.indentWidth),
117-
lineFeed: _parseLineFeed(options.linefeed),
118-
sourceMap: _enableSourceMaps(options));
88+
if (isMainThread == true) {
89+
var worker = Worker(p.current, WorkerOptions(workerData: {options}));
90+
worker.on('message', (CompileResult msg) => result = msg);
91+
worker.on('error', (JSError error) {
92+
jsThrow(_wrapException(error));
93+
});
11994
} else {
120-
throw ArgumentError("Either options.data or options.file must be set.");
95+
if (options.data != null) {
96+
result = await compileStringAsync(options.data,
97+
nodeImporter: _parseImporter(options, start),
98+
functions: _parseFunctions(options, asynch: true),
99+
syntax: isTruthy(options.indentedSyntax) ? Syntax.sass : null,
100+
style: _parseOutputStyle(options.outputStyle),
101+
useSpaces: options.indentType != 'tab',
102+
indentWidth: _parseIndentWidth(options.indentWidth),
103+
lineFeed: _parseLineFeed(options.linefeed),
104+
url: options.file == null ? 'stdin' : p.toUri(file).toString(),
105+
sourceMap: _enableSourceMaps(options));
106+
} else if (options.file != null) {
107+
result = await compileAsync(file,
108+
nodeImporter: _parseImporter(options, start),
109+
functions: _parseFunctions(options, asynch: true),
110+
syntax: isTruthy(options.indentedSyntax) ? Syntax.sass : null,
111+
style: _parseOutputStyle(options.outputStyle),
112+
useSpaces: options.indentType != 'tab',
113+
indentWidth: _parseIndentWidth(options.indentWidth),
114+
lineFeed: _parseLineFeed(options.linefeed),
115+
sourceMap: _enableSourceMaps(options));
116+
} else {
117+
throw ArgumentError("Either options.data or options.file must be set.");
118+
}
119+
ParentPort.postMessage(result, PortOptions());
121120
}
122121

123122
return _newRenderResult(options, result, start);

lib/src/node/worker_threads.dart

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,52 @@
11
// Copyright 2017 Google Inc. Use of this source code is governed by an
22
// MIT-style license that can be found in the LICENSE file or at
33
// https://opensource.org/licenses/MIT.
4+
@JS()
5+
library worker_threads;
46

57
import 'package:js/js.dart';
8+
import 'package:js/js_util.dart';
69

7-
class WorkerOptions extends Object {
10+
@JS()
11+
external Object _requireWorkerThreads(String path);
12+
13+
final workers = _requireWorkerThreads("worker_threads");
14+
15+
@JS()
16+
external Object get workerData;
17+
18+
@JS()
19+
external bool get isMainThread;
20+
21+
@JS()
22+
@anonymous
23+
class WorkerOptions {
24+
external factory WorkerOptions(
25+
{List<Object> argv,
26+
Object env,
27+
bool eval,
28+
List<String> execArgv,
29+
Object workerData});
830
}
931

10-
@JS("worker_threads")
32+
@JS()
1133
class Worker {
12-
external Worker on(String message, Function callback);
34+
external void on(String message, Function callback);
1335

14-
external factory Worker(String filename, WorkerOptions options);
36+
external const factory Worker(fileName, WorkerOptions options);
1537
}
1638

17-
@JS("worker_threads")
18-
class ParentPort {
19-
external ParentPort postMessage(Object value,
20-
{List transferList = const []});
39+
@JS()
40+
@anonymous
41+
class PortOptions {
42+
external List get transferList;
43+
external factory PortOptions({List<Object> transferList = const []});
2144
}
2245

46+
@JS()
47+
external ParentPort get parentPort;
48+
49+
@JS()
50+
class ParentPort {
51+
external static void postMessage(Object message, PortOptions options);
52+
}

0 commit comments

Comments
 (0)