@nativescript/windows 0.1.0-alpha.2 → 0.1.0-alpha.21

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.
@@ -0,0 +1,281 @@
1
+ using System;
2
+ using System.Buffers;
3
+ using System.Collections;
4
+ using System.Collections.Concurrent;
5
+ using System.Collections.Generic;
6
+ using System.Linq.Expressions;
7
+ using System.Reflection;
8
+ using System.Text.Json;
9
+ using System.Text.Json.Serialization;
10
+ using System.Threading;
11
+ using System.Threading.Tasks;
12
+
13
+ namespace NativeScriptBridge;
14
+
15
+ // ── JSON source-gen context ───────────────────────────────────────────────────
16
+
17
+ [JsonSerializable(typeof(InvokeRequest))]
18
+ [JsonSourceGenerationOptions(PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)]
19
+ internal partial class BridgeJsonContext : JsonSerializerContext { }
20
+
21
+ // ── JSON wire type ────────────────────────────────────────────────────────────
22
+
23
+ internal sealed record InvokeRequest(
24
+ string? Assembly,
25
+ string? TypeName,
26
+ string? Method,
27
+ int? Handle,
28
+ JsonElement[]? Args
29
+ );
30
+
31
+ // ── cache key structs ─────────────────────────────────────────────────────────
32
+ //
33
+ // Using Type as the key field (rather than Type.FullName) is correct and faster:
34
+ // Type instances are singletons within an AssemblyLoadContext, so reference
35
+ // equality and reference hash codes are sufficient and allocation-free.
36
+
37
+ internal readonly record struct MethodKey(Type Type, string Name, int ArgCount, BindingFlags Flags);
38
+ internal readonly record struct PropKey(Type Type, string Name, BindingFlags Flags);
39
+ internal readonly record struct CtorKey(Type Type, int ArgCount);
40
+
41
+ // ── cache value types ─────────────────────────────────────────────────────────
42
+
43
+ internal readonly struct DispatchEntry(Func<object?, object?[], object?>? invoke, ParameterInfo[] parameters)
44
+ {
45
+ public readonly Func<object?, object?[], object?>? Invoke = invoke;
46
+ public readonly ParameterInfo[] Parameters = parameters;
47
+ public static readonly DispatchEntry Empty = new(null, []);
48
+ }
49
+
50
+ internal readonly struct CtorEntry(ConstructorInfo? ctor, ParameterInfo[] parameters)
51
+ {
52
+ public readonly ConstructorInfo? Ctor = ctor;
53
+ public readonly ParameterInfo[] Parameters = parameters;
54
+ }
55
+
56
+ // ── dispatch result ───────────────────────────────────────────────────────────
57
+
58
+ internal enum DispatchKind : byte { Void, Primitive, Handle, Collection, Members }
59
+
60
+ internal readonly struct DispatchResult
61
+ {
62
+ public static readonly DispatchResult Void =
63
+ new(DispatchKind.Void, null, null, 0, null, null, null, null, null);
64
+
65
+ private readonly DispatchKind _kind;
66
+ private readonly object? _value;
67
+ private readonly Type? _type;
68
+ private readonly int _handle;
69
+ private readonly string? _typeName;
70
+ private readonly string[]? _methods;
71
+ private readonly string[]? _properties;
72
+ private readonly string[]? _staticMethods;
73
+ private readonly string[]? _staticProperties;
74
+
75
+ private DispatchResult(DispatchKind kind, object? value, Type? type, int handle,
76
+ string? typeName, string[]? methods, string[]? props,
77
+ string[]? staticMethods, string[]? staticProps)
78
+ {
79
+ _kind = kind; _value = value; _type = type; _handle = handle;
80
+ _typeName = typeName; _methods = methods; _properties = props;
81
+ _staticMethods = staticMethods; _staticProperties = staticProps;
82
+ }
83
+
84
+ public static DispatchResult Primitive(object value, Type type)
85
+ => new(DispatchKind.Primitive, value, type, 0, null, null, null, null, null);
86
+
87
+ public static DispatchResult Handle(int id, string typeName)
88
+ => new(DispatchKind.Handle, null, null, id, typeName, null, null, null, null);
89
+
90
+ public static DispatchResult Collection(IEnumerable items)
91
+ => new(DispatchKind.Collection, items, null, 0, null, null, null, null, null);
92
+
93
+ public static DispatchResult Members(
94
+ string[] methods, string[] props, string[] staticMethods, string[] staticProps)
95
+ => new(DispatchKind.Members, null, null, 0, null, methods, props, staticMethods, staticProps);
96
+
97
+ internal int HandleId() => _handle;
98
+
99
+ // ── JSON serialisation ────────────────────────────────────────────────────
100
+
101
+ public void WriteTo(Utf8JsonWriter w, JsonSerializerOptions opts)
102
+ {
103
+ switch (_kind)
104
+ {
105
+ case DispatchKind.Void:
106
+ w.WriteNullValue();
107
+ break;
108
+
109
+ case DispatchKind.Primitive:
110
+ JsonSerializer.Serialize(w, _value, _type!, opts);
111
+ break;
112
+
113
+ case DispatchKind.Handle:
114
+ w.WriteStartObject();
115
+ w.WriteNumber("__handle"u8, _handle);
116
+ w.WriteString("__type"u8, _typeName);
117
+ w.WriteEndObject();
118
+ break;
119
+
120
+ case DispatchKind.Collection:
121
+ w.WriteStartArray();
122
+ foreach (var item in (IEnumerable)_value!)
123
+ JsonSerializer.Serialize(w, item, item?.GetType() ?? typeof(object), opts);
124
+ w.WriteEndArray();
125
+ break;
126
+
127
+ case DispatchKind.Members:
128
+ w.WriteStartObject();
129
+ WriteStringArray(w, "methods"u8, _methods!);
130
+ WriteStringArray(w, "properties"u8, _properties!);
131
+ WriteStringArray(w, "staticMethods"u8, _staticMethods!);
132
+ WriteStringArray(w, "staticProperties"u8, _staticProperties!);
133
+ w.WriteEndObject();
134
+ break;
135
+ }
136
+ }
137
+
138
+ private static void WriteStringArray(Utf8JsonWriter w, ReadOnlySpan<byte> name, string[] arr)
139
+ {
140
+ w.WriteStartArray(name);
141
+ foreach (var s in arr) w.WriteStringValue(s);
142
+ w.WriteEndArray();
143
+ }
144
+
145
+ // ── binary serialisation ──────────────────────────────────────────────────
146
+ //
147
+ // Response tags:
148
+ // 0x00 = null 0x01 = false 0x02 = true
149
+ // 0x03 = i32[4] 0x04 = f64[8] 0x05 = string[u32+utf8]
150
+ // 0x06 = handle[i32 + u16+utf8 type]
151
+ // 0x07 = array[u32 count + N tagged items]
152
+ // 0x08 = members{ methods, props, staticMethods, staticProps }
153
+ // 0xFF = error[u32+utf8]
154
+
155
+ public void WriteAsBin(ArrayBufferWriter<byte> outBuf)
156
+ {
157
+ var w = new BinWriter(outBuf);
158
+ switch (_kind)
159
+ {
160
+ case DispatchKind.Void:
161
+ w.WriteByte(0x00);
162
+ break;
163
+
164
+ case DispatchKind.Primitive:
165
+ WritePrimitiveBin(ref w, _value!);
166
+ break;
167
+
168
+ case DispatchKind.Handle:
169
+ w.WriteByte(0x06);
170
+ w.WriteI32(_handle);
171
+ w.WriteString16(_typeName ?? "");
172
+ break;
173
+
174
+ case DispatchKind.Collection:
175
+ var items = new List<object?>();
176
+ foreach (var item in (IEnumerable)_value!) items.Add(item);
177
+ w.WriteByte(0x07);
178
+ w.WriteU32((uint)items.Count);
179
+ foreach (var item in items) WriteValueBin(ref w, item);
180
+ break;
181
+
182
+ case DispatchKind.Members:
183
+ w.WriteByte(0x08);
184
+ WriteStringArrayBin(ref w, _methods!);
185
+ WriteStringArrayBin(ref w, _properties!);
186
+ WriteStringArrayBin(ref w, _staticMethods!);
187
+ WriteStringArrayBin(ref w, _staticProperties!);
188
+ break;
189
+ }
190
+ }
191
+
192
+ private static void WritePrimitiveBin(ref BinWriter w, object value)
193
+ {
194
+ switch (value)
195
+ {
196
+ case bool b: w.WriteByte(b ? (byte)0x02 : (byte)0x01); break;
197
+ case sbyte v: w.WriteByte(0x03); w.WriteI32(v); break;
198
+ case byte v: w.WriteByte(0x03); w.WriteI32(v); break;
199
+ case short v: w.WriteByte(0x03); w.WriteI32(v); break;
200
+ case ushort v: w.WriteByte(0x03); w.WriteI32(v); break;
201
+ case int v: w.WriteByte(0x03); w.WriteI32(v); break;
202
+ case uint v: w.WriteByte(0x04); w.WriteF64(v); break;
203
+ case long v: w.WriteByte(0x04); w.WriteF64(v); break;
204
+ case ulong v: w.WriteByte(0x04); w.WriteF64(v); break;
205
+ case float v: w.WriteByte(0x04); w.WriteF64(v); break;
206
+ case double v: w.WriteByte(0x04); w.WriteF64(v); break;
207
+ case decimal v: w.WriteByte(0x04); w.WriteF64((double)v); break;
208
+ case string s: w.WriteByte(0x05); w.WriteString32(s); break;
209
+ default: w.WriteByte(0x05); w.WriteString32(value.ToString() ?? ""); break;
210
+ }
211
+ }
212
+
213
+ private static void WriteValueBin(ref BinWriter w, object? value)
214
+ {
215
+ if (value is null) { w.WriteByte(0x00); return; }
216
+ var t = value.GetType();
217
+ if (t.IsPrimitive || t == typeof(string) || t == typeof(decimal))
218
+ {
219
+ WritePrimitiveBin(ref w, value);
220
+ return;
221
+ }
222
+ if (value is IEnumerable enumerable)
223
+ {
224
+ var items = new List<object?>();
225
+ foreach (var item in enumerable) items.Add(item);
226
+ w.WriteByte(0x07);
227
+ w.WriteU32((uint)items.Count);
228
+ foreach (var item in items) WriteValueBin(ref w, item);
229
+ return;
230
+ }
231
+ var id = Interlocked.Increment(ref Bridge.s_nextHandle);
232
+ Bridge.s_handles[id] = value;
233
+ w.WriteByte(0x06);
234
+ w.WriteI32(id);
235
+ w.WriteString16(t.FullName ?? t.Name);
236
+ }
237
+
238
+ private static void WriteStringArrayBin(ref BinWriter w, string[] arr)
239
+ {
240
+ w.WriteU16((ushort)arr.Length);
241
+ foreach (var s in arr) w.WriteString16(s);
242
+ }
243
+ }
244
+
245
+ // ── async result helpers ──────────────────────────────────────────────────────
246
+
247
+ internal static class TaskResultCache
248
+ {
249
+ private static readonly ConcurrentDictionary<Type, Func<Task, object?>> s_cache = new();
250
+
251
+ public static object? GetResult(Task task)
252
+ {
253
+ var taskType = task.GetType();
254
+ if (!taskType.IsGenericType) return null;
255
+ var fn = s_cache.GetOrAdd(taskType, static t =>
256
+ {
257
+ var param = Expression.Parameter(typeof(Task));
258
+ Expression body = Expression.Property(Expression.Convert(param, t), "Result");
259
+ if (body.Type.IsValueType) body = Expression.Convert(body, typeof(object));
260
+ return Expression.Lambda<Func<Task, object?>>(body, param).Compile();
261
+ });
262
+ return fn(task);
263
+ }
264
+ }
265
+
266
+ internal static class ValueTaskAsTaskCache
267
+ {
268
+ private static readonly ConcurrentDictionary<Type, Func<object, Task>> s_cache = new();
269
+
270
+ public static Task AsTask(Type valueTaskType, object vt)
271
+ {
272
+ var fn = s_cache.GetOrAdd(valueTaskType, static t =>
273
+ {
274
+ var param = Expression.Parameter(typeof(object));
275
+ var cast = Expression.Convert(param, t);
276
+ var call = Expression.Call(cast, t.GetMethod("AsTask")!);
277
+ return Expression.Lambda<Func<object, Task>>(call, param).Compile();
278
+ });
279
+ return fn(vt);
280
+ }
281
+ }
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nativescript/windows",
3
- "version": "0.1.0-alpha.2",
3
+ "version": "0.1.0-alpha.21",
4
4
  "description": "NativeScript for using Windows v8",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,12 +0,0 @@
1
- const page = new Windows.UI.Xaml.Controls.Page();
2
- const text = new Windows.UI.Xaml.Controls.TextBlock();
3
- text.Text = "Hello from NativeScript on Windows!";
4
- text.FontSize = 24;
5
- text.HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Center;
6
- text.VerticalAlignment = Windows.UI.Xaml.VerticalAlignment.Center;
7
-
8
- const grid = new Windows.UI.Xaml.Controls.Grid();
9
- grid.Children.Append(text);
10
- page.Content = grid;
11
-
12
- Windows.UI.Xaml.Window.Current.Content = page;