@cocreate/render 1.48.2 → 1.49.2
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/.github/workflows/automated.yml +22 -20
- package/package.json +7 -8
- package/src/index.js +43 -42
|
@@ -9,33 +9,36 @@ jobs:
|
|
|
9
9
|
about:
|
|
10
10
|
runs-on: ubuntu-latest
|
|
11
11
|
steps:
|
|
12
|
-
- name: Checkout
|
|
13
|
-
uses: actions/checkout@
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
12
|
+
- name: Checkout repository
|
|
13
|
+
uses: actions/checkout@v7
|
|
14
|
+
|
|
15
|
+
- name: Sync package.json description to GitHub About
|
|
16
|
+
env:
|
|
17
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB }}
|
|
18
|
+
run: |
|
|
19
|
+
DESC=$(jq -r '.description // empty' package.json)
|
|
20
|
+
if [ -n "$DESC" ]; then
|
|
21
|
+
echo "Updating repository description to: $DESC"
|
|
22
|
+
gh api -X PATCH repos/${{ github.repository }} -f description="$DESC"
|
|
23
|
+
else
|
|
24
|
+
echo "No description found in package.json."
|
|
25
|
+
fi
|
|
23
26
|
|
|
24
27
|
release:
|
|
25
28
|
runs-on: ubuntu-latest
|
|
26
29
|
steps:
|
|
27
|
-
- name: Checkout
|
|
28
|
-
uses: actions/checkout@
|
|
30
|
+
- name: Checkout repository
|
|
31
|
+
uses: actions/checkout@v7
|
|
29
32
|
with:
|
|
30
|
-
fetch-depth: 0
|
|
33
|
+
fetch-depth: 0
|
|
34
|
+
token: ${{ secrets.GITHUB }} # Authenticates git CLI for tag/commit pushes
|
|
31
35
|
|
|
32
36
|
- name: Setup Node.js
|
|
33
|
-
uses: actions/setup-node@
|
|
37
|
+
uses: actions/setup-node@v7
|
|
34
38
|
with:
|
|
35
|
-
node-version:
|
|
39
|
+
node-version: '24'
|
|
36
40
|
|
|
37
41
|
- name: Install Semantic Release & Plugins
|
|
38
|
-
# Installs semantic-release and its plugins on the runner
|
|
39
42
|
run: |
|
|
40
43
|
npm install -g semantic-release \
|
|
41
44
|
@semantic-release/changelog \
|
|
@@ -43,12 +46,11 @@ jobs:
|
|
|
43
46
|
@semantic-release/github \
|
|
44
47
|
@semantic-release/git
|
|
45
48
|
|
|
46
|
-
- name: Run Semantic Release
|
|
49
|
+
- name: Run Semantic Release
|
|
47
50
|
id: semantic
|
|
48
|
-
# This will automatically pick up your export default config file in the repository root
|
|
49
51
|
run: npx semantic-release
|
|
50
52
|
env:
|
|
51
|
-
GITHUB_TOKEN: "${{ secrets.
|
|
53
|
+
GITHUB_TOKEN: "${{ secrets.GITHUB }}"
|
|
52
54
|
NPM_TOKEN: "${{ secrets.NPM_TOKEN }}"
|
|
53
55
|
|
|
54
56
|
outputs:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cocreate/render",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.49.2",
|
|
4
4
|
"description": "A simple render component in vanilla javascript. Easily configured using HTML5 attributes and/or JavaScript API.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"render",
|
|
@@ -36,14 +36,14 @@
|
|
|
36
36
|
},
|
|
37
37
|
"main": "./src/index.js",
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@cocreate/actions": "^1.
|
|
40
|
-
"@cocreate/api": "^1.
|
|
41
|
-
"@cocreate/element-prototype": "^1.
|
|
42
|
-
"@cocreate/observer": "^1.
|
|
43
|
-
"@cocreate/utils": "^1.
|
|
39
|
+
"@cocreate/actions": "^1.23.0",
|
|
40
|
+
"@cocreate/api": "^1.27.0",
|
|
41
|
+
"@cocreate/element-prototype": "^1.34.0",
|
|
42
|
+
"@cocreate/observer": "^1.21.0",
|
|
43
|
+
"@cocreate/utils": "^1.50.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@cocreate/webpack": "^1.
|
|
46
|
+
"@cocreate/webpack": "^1.7.0"
|
|
47
47
|
},
|
|
48
48
|
"allowScripts": {
|
|
49
49
|
"@cocreate/actions@1.21.4": true,
|
|
@@ -60,7 +60,6 @@
|
|
|
60
60
|
"@cocreate/render@1.46.1": true,
|
|
61
61
|
"@cocreate/socket-client@1.40.5": true,
|
|
62
62
|
"@cocreate/utils@1.42.2": true,
|
|
63
|
-
"@cocreate/uuid@1.12.4": true,
|
|
64
63
|
"@cocreate/webpack@1.4.3": true
|
|
65
64
|
}
|
|
66
65
|
}
|
package/src/index.js
CHANGED
|
@@ -23,13 +23,13 @@
|
|
|
23
23
|
/*globals CustomEvent*/
|
|
24
24
|
import Actions from "@cocreate/actions";
|
|
25
25
|
import Observer from "@cocreate/observer";
|
|
26
|
-
import uuid from "@cocreate/uuid";
|
|
27
26
|
import {
|
|
28
27
|
queryElements,
|
|
29
28
|
getValueFromObject,
|
|
30
29
|
dotNotationToObject,
|
|
31
30
|
ObjectId,
|
|
32
|
-
|
|
31
|
+
astAsync,
|
|
32
|
+
uuid
|
|
33
33
|
} from "@cocreate/utils";
|
|
34
34
|
import "@cocreate/element-prototype";
|
|
35
35
|
import "./index.css";
|
|
@@ -270,7 +270,7 @@ async function render({
|
|
|
270
270
|
} else {
|
|
271
271
|
// TODO: if $auto here every subsequent clone will have same value, not replacing here will apply unique value to each clone
|
|
272
272
|
if (key === "$auto")
|
|
273
|
-
key = key.replace(/\$auto/g,
|
|
273
|
+
key = key.replace(/\$auto/g, uuid(6));
|
|
274
274
|
|
|
275
275
|
if (key) element[i].setAttribute("render", key);
|
|
276
276
|
|
|
@@ -525,7 +525,7 @@ function cloneTemplate(template) {
|
|
|
525
525
|
|
|
526
526
|
let renderAs = clone.getAttribute("render-as");
|
|
527
527
|
if (renderAs === "$auto") {
|
|
528
|
-
renderAs =
|
|
528
|
+
renderAs = uuid(6);
|
|
529
529
|
clone = clone.outerHTML.replace(/\$auto/g, renderAs);
|
|
530
530
|
}
|
|
531
531
|
|
|
@@ -555,7 +555,7 @@ function insertElement(
|
|
|
555
555
|
) {
|
|
556
556
|
let eid = element.getAttribute("eid");
|
|
557
557
|
if (!eid) {
|
|
558
|
-
eid =
|
|
558
|
+
eid = uuid(6);
|
|
559
559
|
element.setAttribute("eid", eid);
|
|
560
560
|
}
|
|
561
561
|
|
|
@@ -818,6 +818,17 @@ async function renderValues(node, data, key, renderAs, keyPath, parent, index) {
|
|
|
818
818
|
}
|
|
819
819
|
}
|
|
820
820
|
|
|
821
|
+
/**
|
|
822
|
+
* Renders placeholders within a string using asynchronous AST calculations and data context binding.
|
|
823
|
+
*
|
|
824
|
+
* @param {Node} node - The target DOM node (attributes, text nodes, elements).
|
|
825
|
+
* @param {Object} data - The contextual database record or dataset being rendered.
|
|
826
|
+
* @param {string} placeholder - The raw template string containing double curly braces (e.g. "{{ $query('#input').value }}").
|
|
827
|
+
* @param {string} renderAs - Optional alias scope context.
|
|
828
|
+
* @param {HTMLElement} renderedNode - Optional target element where rendering applies.
|
|
829
|
+
* @param {number} index - Optional current iteration index if rendering a list.
|
|
830
|
+
* @returns {Promise<string>} - A promise resolving to the fully processed output string.
|
|
831
|
+
*/
|
|
821
832
|
async function renderValue(
|
|
822
833
|
node,
|
|
823
834
|
data,
|
|
@@ -828,7 +839,7 @@ async function renderValue(
|
|
|
828
839
|
) {
|
|
829
840
|
let output = placeholder;
|
|
830
841
|
|
|
831
|
-
// Determine the actual HTMLElement for
|
|
842
|
+
// Determine the actual HTMLElement for astAsync
|
|
832
843
|
// If the node is not an Element (nodeType 1), get its owner or parent element.
|
|
833
844
|
// This safely covers Attributes (ownerElement), Text, Comments, etc. (parentElement)
|
|
834
845
|
let contextElement = node;
|
|
@@ -836,9 +847,8 @@ async function renderValue(
|
|
|
836
847
|
contextElement = node.ownerElement || node.parentElement;
|
|
837
848
|
}
|
|
838
849
|
|
|
839
|
-
//
|
|
840
|
-
|
|
841
|
-
let regex = /\{\{((?:(?!\{\{|\}\})[\s\S])+?)\}\}/;
|
|
850
|
+
// Matches ONLY the innermost {{ }} brackets to prevent greedy-matching nested boundaries.
|
|
851
|
+
let regex = /\{\{\s*((?:(?!\{\{|\}\})[\s\S])+?)\s*\}\}/;
|
|
842
852
|
let omitted = {};
|
|
843
853
|
|
|
844
854
|
let match;
|
|
@@ -855,15 +865,28 @@ async function renderValue(
|
|
|
855
865
|
// --- UNIFIED PARSING PROCESS ---
|
|
856
866
|
let preProcessed = placeholderContent;
|
|
857
867
|
|
|
858
|
-
//
|
|
868
|
+
// Build unified evaluation sandbox inheriting state & local indices
|
|
869
|
+
const sandboxContext = {
|
|
870
|
+
data: data,
|
|
871
|
+
$data: data,
|
|
872
|
+
index: index,
|
|
873
|
+
$index: index,
|
|
874
|
+
...data // Expose data fields natively so they are available as local sandbox variables
|
|
875
|
+
};
|
|
876
|
+
|
|
877
|
+
// 1. PRE-PROCESSOR FOR QUOTED OPERATORS (Saves and processes quoted formulas first)
|
|
859
878
|
let quoteRegex = /(['"])(.*?)\1/g;
|
|
860
879
|
let quoteMatch;
|
|
861
880
|
let replacements = [];
|
|
862
881
|
while ((quoteMatch = quoteRegex.exec(preProcessed)) !== null) {
|
|
863
882
|
let quoteType = quoteMatch[1];
|
|
864
883
|
let content = quoteMatch[2];
|
|
865
|
-
if (content.trim().startsWith('
|
|
866
|
-
let resolved = await
|
|
884
|
+
if (content.trim().startsWith('\u0024')) {
|
|
885
|
+
let resolved = await astAsync({
|
|
886
|
+
executeAST: content,
|
|
887
|
+
node: contextElement,
|
|
888
|
+
sandbox: sandboxContext
|
|
889
|
+
});
|
|
867
890
|
if (resolved === null || resolved === undefined) resolved = "";
|
|
868
891
|
replacements.push({
|
|
869
892
|
original: quoteMatch[0],
|
|
@@ -876,11 +899,12 @@ async function renderValue(
|
|
|
876
899
|
preProcessed = preProcessed.replace(r.original, r.replacement);
|
|
877
900
|
}
|
|
878
901
|
|
|
879
|
-
// 2. PRE-PROCESSOR: Resolve unquoted DOM selectors, custom operators, and CRUD JSON
|
|
880
|
-
preProcessed = await
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
902
|
+
// 2. PRE-PROCESSOR: Resolve unquoted DOM selectors, custom operators, and CRUD JSON formulas
|
|
903
|
+
preProcessed = await astAsync({
|
|
904
|
+
executeAST: preProcessed,
|
|
905
|
+
node: contextElement,
|
|
906
|
+
sandbox: sandboxContext
|
|
907
|
+
});
|
|
884
908
|
|
|
885
909
|
// 3. DATA LOOKUP: Resolve simple keys from the provided data object
|
|
886
910
|
// Keep `node` here because getRenderValue needs to look up the attribute cache!
|
|
@@ -890,32 +914,9 @@ async function renderValue(
|
|
|
890
914
|
preProcessed,
|
|
891
915
|
renderAs
|
|
892
916
|
);
|
|
893
|
-
|
|
894
|
-
// // 4. EXPRESSION EVALUATOR: Handle Math and Ternary logic
|
|
895
|
-
// if (value === undefined || value === null) {
|
|
896
|
-
// const dataProxy = new Proxy(data || {}, {
|
|
897
|
-
// get(target, prop) {
|
|
898
|
-
// if (typeof prop !== "string") return target[prop];
|
|
899
|
-
// if (prop in target) return target[prop];
|
|
900
|
-
// return getRenderValue(node, data, prop, renderAs);
|
|
901
|
-
// },
|
|
902
|
-
// has(target, prop) {
|
|
903
|
-
// if (typeof prop !== "string") return prop in target;
|
|
904
|
-
// return true;
|
|
905
|
-
// }
|
|
906
|
-
// });
|
|
907
|
-
|
|
908
|
-
// const parsedValue = safeParse(preProcessed, dataProxy);
|
|
909
|
-
|
|
910
|
-
// if (parsedValue !== null) {
|
|
911
|
-
// value = parsedValue;
|
|
912
|
-
// } else if (preProcessed !== placeholderContent) {
|
|
913
|
-
// value = preProcessed;
|
|
914
|
-
// }
|
|
915
|
-
// }
|
|
916
917
|
}
|
|
917
918
|
} catch (error) {
|
|
918
|
-
console.error(error);
|
|
919
|
+
console.error("[Renderer AST Bridge] Value computation error:", error);
|
|
919
920
|
}
|
|
920
921
|
|
|
921
922
|
// Replace the placeholder with the resolved value
|
|
@@ -981,7 +982,7 @@ function getRenderValue(node, data, key, renderAs) {
|
|
|
981
982
|
} else if (key === "object" || key === "_id")
|
|
982
983
|
value = ObjectId().toString();
|
|
983
984
|
else if (key === "uuid") {
|
|
984
|
-
value =
|
|
985
|
+
value = uuid(6);
|
|
985
986
|
} else if (parent.source) {
|
|
986
987
|
Data = parent.source.data;
|
|
987
988
|
} else if (parent.parent) {
|