Skip to content

Commit ad65b61

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 c0137eb commit ad65b61

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
@@ -27,6 +27,7 @@ import 'node/render_result.dart';
2727
import 'node/types.dart';
2828
import 'node/value.dart';
2929
import 'node/utils.dart';
30+
import 'node/worker_threads.dart';
3031
import 'parse/scss.dart';
3132
import 'syntax.dart';
3233
import 'value.dart';
@@ -63,56 +64,54 @@ void main() {
6364
/// [render]: https://github.com/sass/node-sass#options
6465
void _render(
6566
RenderOptions options, void callback(JSError error, RenderResult result)) {
66-
if (options.fiber != null) {
67-
options.fiber.call(allowInterop(() {
68-
try {
69-
callback(null, _renderSync(options));
70-
} catch (error) {
71-
callback(error as JSError, null);
72-
}
73-
return null;
74-
})).run();
75-
} else {
76-
_renderAsync(options).then((result) {
77-
callback(null, result);
78-
}, onError: (Object error, StackTrace stackTrace) {
79-
if (error is SassException) {
80-
callback(_wrapException(error), null);
81-
} else {
82-
callback(_newRenderError(error.toString(), status: 3), null);
83-
}
84-
});
85-
}
67+
_renderAsync(options).then((result) {
68+
callback(null, result);
69+
}, onError: (Object error, StackTrace stackTrace) {
70+
if (error is SassException) {
71+
callback(_wrapException(error), null);
72+
} else {
73+
callback(_newRenderError(error.toString(), status: 3), null);
74+
}
75+
});
8676
}
8777

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

118117
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)