dolphin-client 1.0.0 → 1.0.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.
package/README.md CHANGED
@@ -20,14 +20,22 @@ By breathing life back into standard HTML, we have resurrected the simplicity of
20
20
 
21
21
  ---
22
22
 
23
+ ## Documentation
24
+
25
+ > [!TIP]
26
+ > 📖 Read our comprehensive **[Full Developer Tutorial & Integration Guide](file:///c:/Users/USER/Desktop/dolphin-test/fulltutorial.md)** for detailed guides, Next.js setups, WebRTC intercoms, global stores, drag-and-drop sortable lists, and real-world examples!
27
+
28
+ ---
29
+
23
30
  ## Features
24
31
 
25
32
  - **Hookless Reactivity**: Bind topics to DOM elements via HTML data attributes—no React, Vue, or Angular state management required.
33
+ - **Svelte-Style Templates Compiler**: Native browser compiler supporting Svelte-style loop blocks (`{#each ... as ...}`), multi-level nested conditionals (`{#if} / {:else if} / {:else}`), loop indices (`index`), optional chaining, and dynamic attribute interpolation.
26
34
  - **Unified Event Binding**: Loop-based browser event handling for values (`data-rt-push`) and actions (`data-rt-[event]` / `data-api-[event]`).
27
35
  - **Context API/Prop drilling in Pure DOM**: Crawls up the DOM tree (`getClosestContext`) to fetch parent contexts and inject parameters.
28
36
  - **REST API + Realtime Hybrid Support**: Evaluates templates (`data-rt-template`) on initial HTTP fetches (`data-api-get`) and transitions seamlessly to real-time WebSockets on connection.
29
37
  - **WebRTC Intercom Signaling**: Built-in methods to handle peer connections, track negotiation, ICE candidates, and signaling.
30
- - **Ultralight weight**: Zero external dependencies, pure browser-native runtime APIs.
38
+ - **Ultralight weight**: Zero external dependencies, pure browser-native runtime APIs (~77KB bundle!).
31
39
 
32
40
  ### Method 1: NPM (For Modern Bundlers)
33
41
  ```bash
@@ -788,6 +788,108 @@ var DolphinModule = (() => {
788
788
  }
789
789
  return template;
790
790
  }
791
+ function renderTemplate(templateStr, context) {
792
+ if (!templateStr.includes("{#if") && !templateStr.includes("{#each")) {
793
+ let result = templateStr;
794
+ for (let key in context) {
795
+ const escapedKey = key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
796
+ result = result.replace(new RegExp(`\\{\\{${escapedKey}\\}\\}`, "g"), context[key] !== void 0 && context[key] !== null ? context[key] : "");
797
+ }
798
+ return result;
799
+ }
800
+ try {
801
+ const escapeString = (str) => {
802
+ return str.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t");
803
+ };
804
+ let compiled = 'let out = "";\n';
805
+ let lastIndex = 0;
806
+ const regex = /(\{\{([\s\S]*?)\}\}|\{#if\s+([\s\S]*?)\}|\{:else\s+if\s+([\s\S]*?)\}|\{:else\}|\{\/if\}|\{#each\s+([\s\S]*?)\s+as\s+([a-zA-Z_$][a-zA-Z0-9_$]*)(?:\s*,\s*([a-zA-Z_$][a-zA-Z0-9_$]*))?\}|\{\/each\}|\{([^{}]+?)\})/g;
807
+ const eachStack = [];
808
+ let match;
809
+ while ((match = regex.exec(templateStr)) !== null) {
810
+ const plainText = templateStr.slice(lastIndex, match.index);
811
+ if (plainText) {
812
+ compiled += `out += "${escapeString(plainText)}";
813
+ `;
814
+ }
815
+ const token = match[0];
816
+ if (token.startsWith("{{")) {
817
+ const expr = match[2];
818
+ compiled += `out += (${expr} !== undefined && ${expr} !== null ? ${expr} : "");
819
+ `;
820
+ } else if (token.startsWith("{#if")) {
821
+ const expr = match[3];
822
+ compiled += `if (${expr}) {
823
+ `;
824
+ } else if (token.startsWith("{:else if")) {
825
+ const expr = match[4];
826
+ compiled += `} else if (${expr}) {
827
+ `;
828
+ } else if (token.startsWith("{:else}")) {
829
+ compiled += `} else {
830
+ `;
831
+ } else if (token.startsWith("{/if}")) {
832
+ compiled += `}
833
+ `;
834
+ } else if (token.startsWith("{#each")) {
835
+ const expr = match[5];
836
+ const itemVar = match[6];
837
+ const indexVar = match[7];
838
+ eachStack.push({ indexVar });
839
+ compiled += `if (typeof ${expr} !== "undefined" && ${expr} !== null && Array.isArray(${expr})) {
840
+ `;
841
+ if (indexVar) {
842
+ compiled += ` let ${indexVar} = 0;
843
+ `;
844
+ }
845
+ compiled += ` for (let ${itemVar} of ${expr}) {
846
+ `;
847
+ } else if (token.startsWith("{/each}")) {
848
+ const info = eachStack.pop();
849
+ if (info && info.indexVar) {
850
+ compiled += ` ${info.indexVar}++;
851
+ `;
852
+ }
853
+ compiled += ` }
854
+ }
855
+ `;
856
+ } else if (token.startsWith("{")) {
857
+ const expr = match[8];
858
+ if (expr) {
859
+ compiled += `out += (${expr} !== undefined && ${expr} !== null ? ${expr} : "");
860
+ `;
861
+ }
862
+ }
863
+ lastIndex = regex.lastIndex;
864
+ }
865
+ const remaining = templateStr.slice(lastIndex);
866
+ if (remaining) {
867
+ compiled += `out += "${escapeString(remaining)}";
868
+ `;
869
+ }
870
+ compiled += "return out;\n";
871
+ const fnBody = `
872
+ with (context) {
873
+ try {
874
+ ${compiled}
875
+ } catch (innerErr) {
876
+ console.warn('[Dolphin Template Eval Warning]:', innerErr);
877
+ return '';
878
+ }
879
+ }
880
+ `;
881
+ const fn = new Function("context", fnBody);
882
+ return fn(context);
883
+ } catch (e) {
884
+ console.error("[Dolphin Template Compiler Error]:", e);
885
+ let fallback = templateStr;
886
+ for (let key in context) {
887
+ const escapedKey = key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
888
+ fallback = fallback.replace(new RegExp(`\\{\\{${escapedKey}\\}\\}`, "g"), context[key] !== void 0 && context[key] !== null ? context[key] : "");
889
+ }
890
+ return fallback;
891
+ }
892
+ }
791
893
  function sanitizeHTML(html) {
792
894
  if (typeof document === "undefined") return html;
793
895
  try {
@@ -1188,21 +1290,11 @@ var DolphinModule = (() => {
1188
1290
  if (Array.isArray(result)) {
1189
1291
  let combinedHTML = "";
1190
1292
  for (const item of result) {
1191
- let finalItemHTML = template;
1192
- for (let key in item) {
1193
- const escapedKey = escapeRegExp(key);
1194
- finalItemHTML = finalItemHTML.replace(new RegExp(`\\{\\{${escapedKey}\\}\\}`, "g"), item[key] !== void 0 && item[key] !== null ? item[key] : "");
1195
- }
1196
- combinedHTML += finalItemHTML;
1293
+ combinedHTML += renderTemplate(template, item);
1197
1294
  }
1198
1295
  scheduleDOMUpdate(el, combinedHTML);
1199
1296
  } else {
1200
- let finalHTML = template;
1201
- for (let key in result) {
1202
- const escapedKey = escapeRegExp(key);
1203
- finalHTML = finalHTML.replace(new RegExp(`\\{\\{${escapedKey}\\}\\}`, "g"), result[key] !== void 0 && result[key] !== null ? result[key] : "");
1204
- }
1205
- scheduleDOMUpdate(el, finalHTML);
1297
+ scheduleDOMUpdate(el, renderTemplate(template, result));
1206
1298
  }
1207
1299
  } else {
1208
1300
  if (el.tagName === "INPUT" || el.tagName === "TEXTAREA") {
@@ -1296,21 +1388,11 @@ var DolphinModule = (() => {
1296
1388
  if (Array.isArray(payload)) {
1297
1389
  let combinedHTML = "";
1298
1390
  for (const item of payload) {
1299
- let finalItemHTML = template;
1300
- for (let key in item) {
1301
- const escapedKey = escapeRegExp(key);
1302
- finalItemHTML = finalItemHTML.replace(new RegExp(`\\{\\{${escapedKey}\\}\\}`, "g"), item[key] !== void 0 && item[key] !== null ? item[key] : "");
1303
- }
1304
- combinedHTML += finalItemHTML;
1391
+ combinedHTML += renderTemplate(template, item);
1305
1392
  }
1306
1393
  scheduleDOMUpdate(el, combinedHTML);
1307
1394
  } else {
1308
- let finalHTML = template;
1309
- for (let key in payload) {
1310
- const escapedKey = escapeRegExp(key);
1311
- finalHTML = finalHTML.replace(new RegExp(`\\{\\{${escapedKey}\\}\\}`, "g"), payload[key] !== void 0 && payload[key] !== null ? payload[key] : "");
1312
- }
1313
- scheduleDOMUpdate(el, finalHTML);
1395
+ scheduleDOMUpdate(el, renderTemplate(template, payload));
1314
1396
  }
1315
1397
  return;
1316
1398
  }
package/dist/index.cjs CHANGED
@@ -788,6 +788,108 @@ function attachDOMBinding(clientProto) {
788
788
  }
789
789
  return template;
790
790
  }
791
+ function renderTemplate(templateStr, context) {
792
+ if (!templateStr.includes("{#if") && !templateStr.includes("{#each")) {
793
+ let result = templateStr;
794
+ for (let key in context) {
795
+ const escapedKey = key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
796
+ result = result.replace(new RegExp(`\\{\\{${escapedKey}\\}\\}`, "g"), context[key] !== void 0 && context[key] !== null ? context[key] : "");
797
+ }
798
+ return result;
799
+ }
800
+ try {
801
+ const escapeString = (str) => {
802
+ return str.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t");
803
+ };
804
+ let compiled = 'let out = "";\n';
805
+ let lastIndex = 0;
806
+ const regex = /(\{\{([\s\S]*?)\}\}|\{#if\s+([\s\S]*?)\}|\{:else\s+if\s+([\s\S]*?)\}|\{:else\}|\{\/if\}|\{#each\s+([\s\S]*?)\s+as\s+([a-zA-Z_$][a-zA-Z0-9_$]*)(?:\s*,\s*([a-zA-Z_$][a-zA-Z0-9_$]*))?\}|\{\/each\}|\{([^{}]+?)\})/g;
807
+ const eachStack = [];
808
+ let match;
809
+ while ((match = regex.exec(templateStr)) !== null) {
810
+ const plainText = templateStr.slice(lastIndex, match.index);
811
+ if (plainText) {
812
+ compiled += `out += "${escapeString(plainText)}";
813
+ `;
814
+ }
815
+ const token = match[0];
816
+ if (token.startsWith("{{")) {
817
+ const expr = match[2];
818
+ compiled += `out += (${expr} !== undefined && ${expr} !== null ? ${expr} : "");
819
+ `;
820
+ } else if (token.startsWith("{#if")) {
821
+ const expr = match[3];
822
+ compiled += `if (${expr}) {
823
+ `;
824
+ } else if (token.startsWith("{:else if")) {
825
+ const expr = match[4];
826
+ compiled += `} else if (${expr}) {
827
+ `;
828
+ } else if (token.startsWith("{:else}")) {
829
+ compiled += `} else {
830
+ `;
831
+ } else if (token.startsWith("{/if}")) {
832
+ compiled += `}
833
+ `;
834
+ } else if (token.startsWith("{#each")) {
835
+ const expr = match[5];
836
+ const itemVar = match[6];
837
+ const indexVar = match[7];
838
+ eachStack.push({ indexVar });
839
+ compiled += `if (typeof ${expr} !== "undefined" && ${expr} !== null && Array.isArray(${expr})) {
840
+ `;
841
+ if (indexVar) {
842
+ compiled += ` let ${indexVar} = 0;
843
+ `;
844
+ }
845
+ compiled += ` for (let ${itemVar} of ${expr}) {
846
+ `;
847
+ } else if (token.startsWith("{/each}")) {
848
+ const info = eachStack.pop();
849
+ if (info && info.indexVar) {
850
+ compiled += ` ${info.indexVar}++;
851
+ `;
852
+ }
853
+ compiled += ` }
854
+ }
855
+ `;
856
+ } else if (token.startsWith("{")) {
857
+ const expr = match[8];
858
+ if (expr) {
859
+ compiled += `out += (${expr} !== undefined && ${expr} !== null ? ${expr} : "");
860
+ `;
861
+ }
862
+ }
863
+ lastIndex = regex.lastIndex;
864
+ }
865
+ const remaining = templateStr.slice(lastIndex);
866
+ if (remaining) {
867
+ compiled += `out += "${escapeString(remaining)}";
868
+ `;
869
+ }
870
+ compiled += "return out;\n";
871
+ const fnBody = `
872
+ with (context) {
873
+ try {
874
+ ${compiled}
875
+ } catch (innerErr) {
876
+ console.warn('[Dolphin Template Eval Warning]:', innerErr);
877
+ return '';
878
+ }
879
+ }
880
+ `;
881
+ const fn = new Function("context", fnBody);
882
+ return fn(context);
883
+ } catch (e) {
884
+ console.error("[Dolphin Template Compiler Error]:", e);
885
+ let fallback = templateStr;
886
+ for (let key in context) {
887
+ const escapedKey = key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
888
+ fallback = fallback.replace(new RegExp(`\\{\\{${escapedKey}\\}\\}`, "g"), context[key] !== void 0 && context[key] !== null ? context[key] : "");
889
+ }
890
+ return fallback;
891
+ }
892
+ }
791
893
  function sanitizeHTML(html) {
792
894
  if (typeof document === "undefined") return html;
793
895
  try {
@@ -1188,21 +1290,11 @@ function attachDOMBinding(clientProto) {
1188
1290
  if (Array.isArray(result)) {
1189
1291
  let combinedHTML = "";
1190
1292
  for (const item of result) {
1191
- let finalItemHTML = template;
1192
- for (let key in item) {
1193
- const escapedKey = escapeRegExp(key);
1194
- finalItemHTML = finalItemHTML.replace(new RegExp(`\\{\\{${escapedKey}\\}\\}`, "g"), item[key] !== void 0 && item[key] !== null ? item[key] : "");
1195
- }
1196
- combinedHTML += finalItemHTML;
1293
+ combinedHTML += renderTemplate(template, item);
1197
1294
  }
1198
1295
  scheduleDOMUpdate(el, combinedHTML);
1199
1296
  } else {
1200
- let finalHTML = template;
1201
- for (let key in result) {
1202
- const escapedKey = escapeRegExp(key);
1203
- finalHTML = finalHTML.replace(new RegExp(`\\{\\{${escapedKey}\\}\\}`, "g"), result[key] !== void 0 && result[key] !== null ? result[key] : "");
1204
- }
1205
- scheduleDOMUpdate(el, finalHTML);
1297
+ scheduleDOMUpdate(el, renderTemplate(template, result));
1206
1298
  }
1207
1299
  } else {
1208
1300
  if (el.tagName === "INPUT" || el.tagName === "TEXTAREA") {
@@ -1296,21 +1388,11 @@ function attachDOMBinding(clientProto) {
1296
1388
  if (Array.isArray(payload)) {
1297
1389
  let combinedHTML = "";
1298
1390
  for (const item of payload) {
1299
- let finalItemHTML = template;
1300
- for (let key in item) {
1301
- const escapedKey = escapeRegExp(key);
1302
- finalItemHTML = finalItemHTML.replace(new RegExp(`\\{\\{${escapedKey}\\}\\}`, "g"), item[key] !== void 0 && item[key] !== null ? item[key] : "");
1303
- }
1304
- combinedHTML += finalItemHTML;
1391
+ combinedHTML += renderTemplate(template, item);
1305
1392
  }
1306
1393
  scheduleDOMUpdate(el, combinedHTML);
1307
1394
  } else {
1308
- let finalHTML = template;
1309
- for (let key in payload) {
1310
- const escapedKey = escapeRegExp(key);
1311
- finalHTML = finalHTML.replace(new RegExp(`\\{\\{${escapedKey}\\}\\}`, "g"), payload[key] !== void 0 && payload[key] !== null ? payload[key] : "");
1312
- }
1313
- scheduleDOMUpdate(el, finalHTML);
1395
+ scheduleDOMUpdate(el, renderTemplate(template, payload));
1314
1396
  }
1315
1397
  return;
1316
1398
  }
package/dist/index.js CHANGED
@@ -763,6 +763,108 @@ function attachDOMBinding(clientProto) {
763
763
  }
764
764
  return template;
765
765
  }
766
+ function renderTemplate(templateStr, context) {
767
+ if (!templateStr.includes("{#if") && !templateStr.includes("{#each")) {
768
+ let result = templateStr;
769
+ for (let key in context) {
770
+ const escapedKey = key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
771
+ result = result.replace(new RegExp(`\\{\\{${escapedKey}\\}\\}`, "g"), context[key] !== void 0 && context[key] !== null ? context[key] : "");
772
+ }
773
+ return result;
774
+ }
775
+ try {
776
+ const escapeString = (str) => {
777
+ return str.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t");
778
+ };
779
+ let compiled = 'let out = "";\n';
780
+ let lastIndex = 0;
781
+ const regex = /(\{\{([\s\S]*?)\}\}|\{#if\s+([\s\S]*?)\}|\{:else\s+if\s+([\s\S]*?)\}|\{:else\}|\{\/if\}|\{#each\s+([\s\S]*?)\s+as\s+([a-zA-Z_$][a-zA-Z0-9_$]*)(?:\s*,\s*([a-zA-Z_$][a-zA-Z0-9_$]*))?\}|\{\/each\}|\{([^{}]+?)\})/g;
782
+ const eachStack = [];
783
+ let match;
784
+ while ((match = regex.exec(templateStr)) !== null) {
785
+ const plainText = templateStr.slice(lastIndex, match.index);
786
+ if (plainText) {
787
+ compiled += `out += "${escapeString(plainText)}";
788
+ `;
789
+ }
790
+ const token = match[0];
791
+ if (token.startsWith("{{")) {
792
+ const expr = match[2];
793
+ compiled += `out += (${expr} !== undefined && ${expr} !== null ? ${expr} : "");
794
+ `;
795
+ } else if (token.startsWith("{#if")) {
796
+ const expr = match[3];
797
+ compiled += `if (${expr}) {
798
+ `;
799
+ } else if (token.startsWith("{:else if")) {
800
+ const expr = match[4];
801
+ compiled += `} else if (${expr}) {
802
+ `;
803
+ } else if (token.startsWith("{:else}")) {
804
+ compiled += `} else {
805
+ `;
806
+ } else if (token.startsWith("{/if}")) {
807
+ compiled += `}
808
+ `;
809
+ } else if (token.startsWith("{#each")) {
810
+ const expr = match[5];
811
+ const itemVar = match[6];
812
+ const indexVar = match[7];
813
+ eachStack.push({ indexVar });
814
+ compiled += `if (typeof ${expr} !== "undefined" && ${expr} !== null && Array.isArray(${expr})) {
815
+ `;
816
+ if (indexVar) {
817
+ compiled += ` let ${indexVar} = 0;
818
+ `;
819
+ }
820
+ compiled += ` for (let ${itemVar} of ${expr}) {
821
+ `;
822
+ } else if (token.startsWith("{/each}")) {
823
+ const info = eachStack.pop();
824
+ if (info && info.indexVar) {
825
+ compiled += ` ${info.indexVar}++;
826
+ `;
827
+ }
828
+ compiled += ` }
829
+ }
830
+ `;
831
+ } else if (token.startsWith("{")) {
832
+ const expr = match[8];
833
+ if (expr) {
834
+ compiled += `out += (${expr} !== undefined && ${expr} !== null ? ${expr} : "");
835
+ `;
836
+ }
837
+ }
838
+ lastIndex = regex.lastIndex;
839
+ }
840
+ const remaining = templateStr.slice(lastIndex);
841
+ if (remaining) {
842
+ compiled += `out += "${escapeString(remaining)}";
843
+ `;
844
+ }
845
+ compiled += "return out;\n";
846
+ const fnBody = `
847
+ with (context) {
848
+ try {
849
+ ${compiled}
850
+ } catch (innerErr) {
851
+ console.warn('[Dolphin Template Eval Warning]:', innerErr);
852
+ return '';
853
+ }
854
+ }
855
+ `;
856
+ const fn = new Function("context", fnBody);
857
+ return fn(context);
858
+ } catch (e) {
859
+ console.error("[Dolphin Template Compiler Error]:", e);
860
+ let fallback = templateStr;
861
+ for (let key in context) {
862
+ const escapedKey = key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
863
+ fallback = fallback.replace(new RegExp(`\\{\\{${escapedKey}\\}\\}`, "g"), context[key] !== void 0 && context[key] !== null ? context[key] : "");
864
+ }
865
+ return fallback;
866
+ }
867
+ }
766
868
  function sanitizeHTML(html) {
767
869
  if (typeof document === "undefined") return html;
768
870
  try {
@@ -1163,21 +1265,11 @@ function attachDOMBinding(clientProto) {
1163
1265
  if (Array.isArray(result)) {
1164
1266
  let combinedHTML = "";
1165
1267
  for (const item of result) {
1166
- let finalItemHTML = template;
1167
- for (let key in item) {
1168
- const escapedKey = escapeRegExp(key);
1169
- finalItemHTML = finalItemHTML.replace(new RegExp(`\\{\\{${escapedKey}\\}\\}`, "g"), item[key] !== void 0 && item[key] !== null ? item[key] : "");
1170
- }
1171
- combinedHTML += finalItemHTML;
1268
+ combinedHTML += renderTemplate(template, item);
1172
1269
  }
1173
1270
  scheduleDOMUpdate(el, combinedHTML);
1174
1271
  } else {
1175
- let finalHTML = template;
1176
- for (let key in result) {
1177
- const escapedKey = escapeRegExp(key);
1178
- finalHTML = finalHTML.replace(new RegExp(`\\{\\{${escapedKey}\\}\\}`, "g"), result[key] !== void 0 && result[key] !== null ? result[key] : "");
1179
- }
1180
- scheduleDOMUpdate(el, finalHTML);
1272
+ scheduleDOMUpdate(el, renderTemplate(template, result));
1181
1273
  }
1182
1274
  } else {
1183
1275
  if (el.tagName === "INPUT" || el.tagName === "TEXTAREA") {
@@ -1271,21 +1363,11 @@ function attachDOMBinding(clientProto) {
1271
1363
  if (Array.isArray(payload)) {
1272
1364
  let combinedHTML = "";
1273
1365
  for (const item of payload) {
1274
- let finalItemHTML = template;
1275
- for (let key in item) {
1276
- const escapedKey = escapeRegExp(key);
1277
- finalItemHTML = finalItemHTML.replace(new RegExp(`\\{\\{${escapedKey}\\}\\}`, "g"), item[key] !== void 0 && item[key] !== null ? item[key] : "");
1278
- }
1279
- combinedHTML += finalItemHTML;
1366
+ combinedHTML += renderTemplate(template, item);
1280
1367
  }
1281
1368
  scheduleDOMUpdate(el, combinedHTML);
1282
1369
  } else {
1283
- let finalHTML = template;
1284
- for (let key in payload) {
1285
- const escapedKey = escapeRegExp(key);
1286
- finalHTML = finalHTML.replace(new RegExp(`\\{\\{${escapedKey}\\}\\}`, "g"), payload[key] !== void 0 && payload[key] !== null ? payload[key] : "");
1287
- }
1288
- scheduleDOMUpdate(el, finalHTML);
1370
+ scheduleDOMUpdate(el, renderTemplate(template, payload));
1289
1371
  }
1290
1372
  return;
1291
1373
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dolphin-client",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "HTML is back! Hookless, framework-agnostic real-time reactive DOM-binding client for Dolphin Server with WebSockets, WebRTC signaling, and offline REST API fallbacks.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",