@lucent-lang/lucent 0.0.4 → 0.1.1

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.
Files changed (152) hide show
  1. package/README.md +97 -0
  2. package/app.plugin.js +46 -10
  3. package/dist/{bench-CR3E7e2e.js → bench-eEez4jhQ.js} +10 -6
  4. package/dist/{build-CAIrRSYA.js → build-CpUjeHFz.js} +1 -1
  5. package/dist/{build-check-QozuNJm5.js → build-check-BA1ZEp9s.js} +28 -13
  6. package/dist/{check-1SCmYlqA.js → check-BZx3FgI6.js} +1 -1
  7. package/dist/cli.js +62 -13
  8. package/dist/{codes-CIuwXt1S.js → codes-D-6LxUqD.js} +163 -7
  9. package/dist/compiler.js +4 -4
  10. package/dist/{dashboard-B-NzjjaN.js → dashboard-CC-HXhcd.js} +2 -2
  11. package/dist/{dev-BYWMP7oC.js → dev-DI5yL8zx.js} +62 -23
  12. package/dist/{diagnostic-BM9sXmwl.js → diagnostic-BvwLZQS1.js} +3 -1
  13. package/dist/{doctor-C0PrfWT6.js → doctor-CTAX3euc.js} +1 -1
  14. package/dist/{doctor-DdR4JnVc.js → doctor-CrgOAV5L.js} +1 -1
  15. package/dist/{explain--vV1oaRl.js → explain-Byit07F-.js} +1 -1
  16. package/dist/{packages-HyskKIsY.js → packages-CSmKeaAh.js} +2 -33
  17. package/dist/pipeline-BM_VM2X_.js +700 -0
  18. package/dist/project-BKNoTEEp.js +342 -0
  19. package/dist/sdk-coverage-iiv3JqMp.js +113 -0
  20. package/dist/sdk-diff-ByJ1Gw-F.js +109 -0
  21. package/dist/sdk-lock-BQn7IyRs.js +38 -0
  22. package/dist/{sdk-prefetch-mo04JDZV.js → sdk-prefetch-Bv2pNega.js} +2 -2
  23. package/dist/{sdk-search-Iv4K3-8a.js → sdk-search-CPGJm_Ne.js} +2 -2
  24. package/dist/{sdk-show-CkrdlqlP.js → sdk-show-BUkLqRnA.js} +5 -4
  25. package/dist/sdk-usage-0ZFMAYg1.js +95 -0
  26. package/dist/src-ChnmWLwn.js +40851 -0
  27. package/dist/trace-Bi4hkmPx.js +139 -0
  28. package/lib/core.cjs +368 -1
  29. package/lib/sdk/android.d.ts +54 -1
  30. package/lib/sdk/compose.d.ts +94 -0
  31. package/lib/sdk/compose.schemas.json.gz +0 -0
  32. package/lib/sdk/core.d.ts +201 -0
  33. package/lib/sdk/ios.d.ts +75 -2
  34. package/lib/sdk/ui.d.ts +129 -0
  35. package/metro/transformer.cjs +11 -2
  36. package/package.json +4 -3
  37. package/runtime/cpp/lucent/abort.cpp +59 -11
  38. package/runtime/cpp/lucent/abort.h +22 -6
  39. package/runtime/cpp/lucent/array.h +12 -2
  40. package/runtime/cpp/lucent/async.h +101 -21
  41. package/runtime/cpp/lucent/bigint.cpp +898 -0
  42. package/runtime/cpp/lucent/bigint.h +302 -0
  43. package/runtime/cpp/lucent/buffer.cpp +228 -0
  44. package/runtime/cpp/lucent/buffer.h +328 -0
  45. package/runtime/cpp/lucent/builtins.cpp +4 -1
  46. package/runtime/cpp/lucent/bytes.h +21 -2
  47. package/runtime/cpp/lucent/callback.cpp +29 -0
  48. package/runtime/cpp/lucent/callback.h +230 -0
  49. package/runtime/cpp/lucent/compute.cpp +370 -0
  50. package/runtime/cpp/lucent/compute.h +455 -0
  51. package/runtime/cpp/lucent/conversions.h +111 -0
  52. package/runtime/cpp/lucent/core.h +16 -5
  53. package/runtime/cpp/lucent/equality.h +107 -28
  54. package/runtime/cpp/lucent/execution.cpp +416 -0
  55. package/runtime/cpp/lucent/execution.h +270 -0
  56. package/runtime/cpp/lucent/extension.cpp +97 -0
  57. package/runtime/cpp/lucent/extension.h +210 -0
  58. package/runtime/cpp/lucent/helpers.h +12 -5
  59. package/runtime/cpp/lucent/items.h +52 -0
  60. package/runtime/cpp/lucent/jserror.cpp +9 -0
  61. package/runtime/cpp/lucent/jserror.h +11 -0
  62. package/runtime/cpp/lucent/jsi/convert.cpp +138 -0
  63. package/runtime/cpp/lucent/jsi/convert.h +128 -59
  64. package/runtime/cpp/lucent/jsi/host.cpp +213 -35
  65. package/runtime/cpp/lucent/jsi/host.h +116 -16
  66. package/runtime/cpp/lucent/json.h +19 -1
  67. package/runtime/cpp/lucent/lifecycle.cpp +260 -0
  68. package/runtime/cpp/lucent/lifecycle.h +124 -0
  69. package/runtime/cpp/lucent/lucent.h +7 -0
  70. package/runtime/cpp/lucent/map.h +41 -7
  71. package/runtime/cpp/lucent/native.cpp +35 -47
  72. package/runtime/cpp/lucent/native.h +116 -26
  73. package/runtime/cpp/lucent/number.cpp +38 -38
  74. package/runtime/cpp/lucent/number.h +33 -0
  75. package/runtime/cpp/lucent/operation.h +65 -0
  76. package/runtime/cpp/lucent/ops.h +14 -6
  77. package/runtime/cpp/lucent/platform/android.cpp +223 -10
  78. package/runtime/cpp/lucent/platform/android.h +227 -4
  79. package/runtime/cpp/lucent/platform/android_activity.cpp +258 -0
  80. package/runtime/cpp/lucent/platform/android_requests.h +140 -0
  81. package/runtime/cpp/lucent/platform/compose.h +256 -0
  82. package/runtime/cpp/lucent/platform/ios.h +325 -25
  83. package/runtime/cpp/lucent/platform/ios.mm +1 -14
  84. package/runtime/cpp/lucent/platform/ios_ui.h +192 -0
  85. package/runtime/cpp/lucent/platform/ios_ui.mm +454 -0
  86. package/runtime/cpp/lucent/platform/swiftui.h +190 -0
  87. package/runtime/cpp/lucent/presentation.cpp +11 -0
  88. package/runtime/cpp/lucent/presentation.h +109 -0
  89. package/runtime/cpp/lucent/reactive.cpp +406 -0
  90. package/runtime/cpp/lucent/reactive.h +566 -0
  91. package/runtime/cpp/lucent/report.cpp +40 -0
  92. package/runtime/cpp/lucent/report.h +16 -0
  93. package/runtime/cpp/lucent/resource.cpp +83 -0
  94. package/runtime/cpp/lucent/resource.h +75 -0
  95. package/runtime/cpp/lucent/scheduler.cpp +38 -124
  96. package/runtime/cpp/lucent/scheduler.h +102 -83
  97. package/runtime/cpp/lucent/scope.cpp +308 -0
  98. package/runtime/cpp/lucent/scope.h +452 -0
  99. package/runtime/cpp/lucent/sizing.h +263 -0
  100. package/runtime/cpp/lucent/slots.h +231 -0
  101. package/runtime/cpp/lucent/trace.cpp +539 -0
  102. package/runtime/cpp/lucent/trace.h +251 -0
  103. package/runtime/cpp/lucent/transport.cpp +9 -0
  104. package/runtime/cpp/lucent/transport.h +341 -0
  105. package/runtime/cpp/lucent/view.cpp +123 -0
  106. package/runtime/cpp/lucent/view.h +157 -0
  107. package/runtime/cpp/rn/LucentComponentView.h +121 -0
  108. package/runtime/cpp/rn/LucentComponentView.mm +479 -0
  109. package/runtime/cpp/rn/LucentModule.cpp +37 -7
  110. package/runtime/cpp/rn/LucentModule.h +3 -0
  111. package/runtime/cpp/rn/LucentViewChildren.h +80 -0
  112. package/runtime/cpp/rn/LucentViewChildren.mm +211 -0
  113. package/runtime/cpp/rn/LucentViewRegistry.h +62 -0
  114. package/runtime/cpp/rn/LucentViewRequests.cpp +91 -0
  115. package/runtime/cpp/rn/LucentViewRequests.h +104 -0
  116. package/runtime/cpp/rn/LucentViewSizing.h +345 -0
  117. package/runtime/cpp/rn/LucentViewSlots.h +242 -0
  118. package/runtime/cpp/rn/LucentViewValues.h +125 -0
  119. package/runtime/cpp/rn/LucentViews.h +440 -0
  120. package/runtime/cpp/rn/LucentViewsAndroid.cpp +439 -0
  121. package/runtime/cpp/rn/LucentViewsAndroid.h +138 -0
  122. package/runtime/cpp/third_party/dragonbox/LICENSE-Boost +23 -0
  123. package/runtime/cpp/third_party/dragonbox/README.md +16 -0
  124. package/runtime/cpp/third_party/dragonbox/dragonbox.h +4440 -0
  125. package/runtime/js/index.d.ts +11 -1
  126. package/runtime/js/index.js +84 -8
  127. package/runtime/js/views.d.ts +38 -0
  128. package/runtime/js/views.js +226 -0
  129. package/runtime/native/android/CMakeLists.txt +4 -1
  130. package/runtime/native/android/src/compose/java/dev/lucent/compose/CompositionRules.kt +44 -0
  131. package/runtime/native/android/src/compose/java/dev/lucent/compose/LucentComposition.kt +161 -0
  132. package/runtime/native/android/src/main/java/dev/lucent/LucentActivities.java +292 -0
  133. package/runtime/native/android/src/main/java/dev/lucent/LucentChildren.java +174 -0
  134. package/runtime/native/android/src/main/java/dev/lucent/LucentHostView.java +232 -0
  135. package/runtime/native/android/src/main/java/dev/lucent/LucentInitializer.java +46 -0
  136. package/runtime/native/android/src/main/java/dev/lucent/LucentPackage.java +4 -3
  137. package/runtime/native/android/src/main/java/dev/lucent/LucentRequestActivity.java +92 -0
  138. package/runtime/native/android/src/main/java/dev/lucent/LucentSlotView.java +102 -0
  139. package/runtime/native/android/src/main/java/dev/lucent/LucentViewManager.java +149 -0
  140. package/runtime/native/android/src/main/java/dev/lucent/LucentViewManagers.java +16 -0
  141. package/runtime/native/android/src/main/java/dev/lucent/LucentViews.java +44 -0
  142. package/runtime/test/jsi/harness.cpp +9 -0
  143. package/schemas/build.schema.json +96 -1
  144. package/schemas/check.schema.json +56 -1
  145. package/schemas/lucent.schema.json +495 -9
  146. package/schemas/sdk-diff.schema.json +70 -0
  147. package/schemas/sdk-lock.schema.json +67 -0
  148. package/ts-plugin/index.js +85 -4
  149. package/dist/pipeline-CH7-2cxu.js +0 -232
  150. package/dist/project-D8tEet0k.js +0 -150
  151. package/dist/sdk-coverage-BoW_3Efd.js +0 -64
  152. package/dist/src-BD7f1_aZ.js +0 -11493
@@ -7,8 +7,13 @@
7
7
  //
8
8
  // Coroutine parameters are always taken by value: a coroutine frame must not
9
9
  // hold references to its caller's locals.
10
+ //
11
+ // A promise belongs to the execution context it was made in, and a
12
+ // continuation to the context that registered it, where it resumes; a
13
+ // coroutine therefore stays on the context it started on.
10
14
  #pragma once
11
15
 
16
+ #include <atomic>
12
17
  #include <coroutine>
13
18
  #include <exception>
14
19
  #include <functional>
@@ -32,37 +37,102 @@ namespace detail {
32
37
  template <class T>
33
38
  using Stored = std::conditional_t<std::is_void_v<T>, Undefined, T>;
34
39
 
40
+ /// A continuation and the context that registered it, where it runs.
41
+ struct Waiter {
42
+ ContextRef context;
43
+ std::function<void()> run;
44
+ };
45
+
46
+ /// Runs `waiter` as a microtask if its context is the calling thread's,
47
+ /// else posts it there.
48
+ inline void dispatch(Waiter& waiter) {
49
+ ExecutionContext& target = ExecutionContext::of(waiter.context);
50
+
51
+ if (target.isCurrent()) {
52
+ target.enqueueMicrotask(std::move(waiter.run));
53
+ } else {
54
+ target.post(std::move(waiter.run));
55
+ }
56
+ }
57
+
58
+ /// A promise's state changes only on its owner, the context it was made
59
+ /// in: settlement or registration from another thread is posted there. Once
60
+ /// settled it never changes, so any thread may read it.
35
61
  template <class T>
36
- struct PromiseState {
62
+ struct PromiseState : std::enable_shared_from_this<PromiseState<T>> {
37
63
  enum class Status : uint8_t { Pending, Fulfilled, Rejected };
38
- Status status = Status::Pending;
64
+
65
+ const ContextRef owner = ExecutionContext::currentRef();
66
+ std::atomic<Status> status{Status::Pending};
39
67
  std::optional<Stored<T>> value;
40
68
  Error error;
41
- std::vector<std::function<void()>> waiters;
69
+ std::vector<Waiter> waiters;
70
+
71
+ Status settledAs() const { return status.load(std::memory_order_acquire); }
42
72
 
43
73
  void fulfill(Stored<T> v) {
44
- if (status != Status::Pending) return;
74
+ if (!onOwner()) {
75
+ toOwner([self = this->shared_from_this(), v = std::move(v)]() mutable { self->fulfill(std::move(v)); });
76
+ return;
77
+ }
78
+
79
+ if (status.load(std::memory_order_relaxed) != Status::Pending) return;
80
+
45
81
  value = std::move(v);
46
- status = Status::Fulfilled;
82
+ status.store(Status::Fulfilled, std::memory_order_release);
47
83
  flush();
48
84
  }
85
+
49
86
  void reject(Error e) {
50
- if (status != Status::Pending) return;
87
+ if (!onOwner()) {
88
+ toOwner([self = this->shared_from_this(), e = std::move(e)]() mutable { self->reject(std::move(e)); });
89
+ return;
90
+ }
91
+
92
+ if (status.load(std::memory_order_relaxed) != Status::Pending) return;
93
+
51
94
  error = std::move(e);
52
- status = Status::Rejected;
95
+ status.store(Status::Rejected, std::memory_order_release);
53
96
  flush();
54
97
  }
55
- /// Runs `f` as a microtask once settled. Callers hold the Lucent lock.
98
+
99
+ /// Runs `f` once settled, as a microtask of the calling thread's context
100
+ /// (the legacy module context outside any).
56
101
  void onSettled(std::function<void()> f) {
57
- if (status == Status::Pending) waiters.push_back(std::move(f));
58
- else Scheduler::instance().enqueueMicrotask(std::move(f));
102
+ Waiter waiter{ExecutionContext::currentRef(), std::move(f)};
103
+
104
+ if (onOwner()) {
105
+ add(std::move(waiter));
106
+ return;
107
+ }
108
+
109
+ if (settledAs() != Status::Pending) {
110
+ dispatch(waiter);
111
+ return;
112
+ }
113
+
114
+ toOwner([self = this->shared_from_this(), waiter = std::move(waiter)]() mutable { self->add(std::move(waiter)); });
59
115
  }
60
116
 
61
117
  private:
118
+ bool onOwner() const { return owner ? owner->isCurrent() : Scheduler::lock().heldByCurrentThread(); }
119
+
120
+ /// Dropped, with what it carries, if the owner has shut down.
121
+ void toOwner(Job job) { ExecutionContext::of(owner).post(std::move(job)); }
122
+
123
+ /// A registration posted from another context, now on the owner.
124
+ void add(Waiter waiter) {
125
+ if (status.load(std::memory_order_relaxed) == Status::Pending) {
126
+ waiters.push_back(std::move(waiter));
127
+ } else {
128
+ dispatch(waiter);
129
+ }
130
+ }
131
+
62
132
  void flush() {
63
133
  auto ws = std::move(waiters);
64
134
  waiters.clear();
65
- for (auto& w : ws) Scheduler::instance().enqueueMicrotask(std::move(w));
135
+ for (auto& w : ws) dispatch(w);
66
136
  }
67
137
  };
68
138
 
@@ -99,28 +169,29 @@ class Promise {
99
169
  Promise() : s_(std::make_shared<State>()) {}
100
170
  explicit Promise(std::shared_ptr<State> s) : s_(std::move(s)) {}
101
171
 
172
+ // A new state is not shared yet: it settles here, whatever its owner.
102
173
  static Promise resolved(detail::Stored<T> v) {
103
174
  Promise p;
104
- p.s_->fulfill(std::move(v));
175
+ p.s_->value = std::move(v);
176
+ p.s_->status.store(State::Status::Fulfilled, std::memory_order_relaxed);
105
177
  return p;
106
178
  }
107
179
  static Promise resolved()
108
180
  requires std::is_void_v<T>
109
181
  {
110
- Promise p;
111
- p.s_->fulfill(undefined);
112
- return p;
182
+ return resolved(undefined);
113
183
  }
114
184
  static Promise rejected(Error e) {
115
185
  Promise p;
116
- p.s_->reject(std::move(e));
186
+ p.s_->error = std::move(e);
187
+ p.s_->status.store(State::Status::Rejected, std::memory_order_relaxed);
117
188
  return p;
118
189
  }
119
190
 
120
191
  void resolve(detail::Stored<T> v) const { s_->fulfill(std::move(v)); }
121
192
  void reject(Error e) const { s_->reject(std::move(e)); }
122
- bool settled() const { return s_->status != State::Status::Pending; }
123
- bool fulfilled() const { return s_->status == State::Status::Fulfilled; }
193
+ bool settled() const { return s_->settledAs() != State::Status::Pending; }
194
+ bool fulfilled() const { return s_->settledAs() == State::Status::Fulfilled; }
124
195
  const detail::Stored<T>& value() const { return *s_->value; }
125
196
  const Error& error() const { return s_->error; }
126
197
  void onSettled(std::function<void()> f) const { s_->onSettled(std::move(f)); }
@@ -131,18 +202,27 @@ class Promise {
131
202
  s_->onSettled([h]() mutable { h.resume(); });
132
203
  }
133
204
  T await_resume() const {
134
- if (s_->status == State::Status::Rejected) throw Exception(s_->error);
205
+ if (s_->settledAs() == State::Status::Rejected) throw Exception(s_->error);
135
206
  if constexpr (!std::is_void_v<T>) return *s_->value;
136
207
  }
137
208
 
138
209
  const void* identity() const { return s_.get(); }
139
- friend bool strictEquals(const Promise& a, const Promise& b) { return a.s_ == b.s_; }
140
- friend String toJsString(const Promise&) { return String::fromLatin1("[object Promise]"); }
141
210
 
142
211
  private:
143
212
  std::shared_ptr<State> s_;
144
213
  };
145
214
 
215
+ template <class T>
216
+ String toJsString(const Promise<T>&) {
217
+ return String::fromLatin1("[object Promise]");
218
+ }
219
+
220
+ /// `===`: the same promise.
221
+ template <class T>
222
+ bool strictEquals(const Promise<T>& a, const Promise<T>& b) {
223
+ return a.identity() == b.identity();
224
+ }
225
+
146
226
  template <class T>
147
227
  Promise<T> detail::PromiseTypeBase<T>::get_return_object() {
148
228
  return Promise<T>(state);