[{"data":1,"prerenderedAt":1022},["ShallowReactive",2],{"doc:\u002Fguides\u002Freaders":3,"nav:guides":972},{"doc":4,"source":971},{"id":5,"title":6,"body":7,"description":964,"extension":965,"meta":966,"navigation":311,"path":967,"seo":968,"stem":969,"__hash__":970},"guides\u002Fguides\u002Freaders.md","Readers",{"type":8,"value":9,"toc":958},"minimark",[10,14,27,32,42,193,204,222,226,449,452,456,459,892,922,932,936,947,954],[11,12,6],"h1",{"id":13},"readers",[15,16,17,18,22,23,26],"p",{},"A reader serves modules or resources for a URI scheme from your program. Pkl asks the reader whenever a module imports ",[19,20,21],"code",{},"scheme:..."," or calls ",[19,24,25],{},"read(\"scheme:...\")",", and the answer never touches the disk unless the reader reads it.",[28,29,31],"h2",{"id":30},"built-in-readers","Built-in readers",[15,33,34,37,38,41],{},[19,35,36],{},"reader.Embed"," serves a fixed table, such as files compiled in with ",[19,39,40],{},"@embedFile",":",[43,44,49],"pre",{"className":45,"code":46,"language":47,"meta":48,"style":48},"language-zig shiki shiki-themes github-light github-dark","var embedded = zig_pkl.reader.Embed{\n    .scheme_name = \"embedded\",\n    .entries = &.{\n        .{ .path = \"\u002Fbase.pkl\", .contents = @embedFile(\"pkl\u002Fbase.pkl\") },\n        .{ .path = \"\u002Fservices\u002Fapi.pkl\", .contents = @embedFile(\"pkl\u002Fservices\u002Fapi.pkl\") },\n    },\n};\n","zig","",[19,50,51,85,103,119,154,181,187],{"__ignoreMap":48},[52,53,56,60,64,67,70,74,77,79,82],"span",{"class":54,"line":55},"line",1,[52,57,59],{"class":58},"szBVR","var",[52,61,63],{"class":62},"s4XuR"," embedded",[52,65,66],{"class":58}," =",[52,68,69],{"class":62}," zig_pkl",[52,71,73],{"class":72},"sVt8B",".",[52,75,76],{"class":62},"reader",[52,78,73],{"class":72},[52,80,81],{"class":62},"Embed",[52,83,84],{"class":72},"{\n",[52,86,88,91,94,96,100],{"class":54,"line":87},2,[52,89,90],{"class":72},"    .",[52,92,93],{"class":62},"scheme_name",[52,95,66],{"class":58},[52,97,99],{"class":98},"sZZnC"," \"embedded\"",[52,101,102],{"class":72},",\n",[52,104,106,108,111,113,116],{"class":54,"line":105},3,[52,107,90],{"class":72},[52,109,110],{"class":62},"entries",[52,112,66],{"class":58},[52,114,115],{"class":58}," &",[52,117,118],{"class":72},".{\n",[52,120,122,125,128,130,133,136,139,141,145,148,151],{"class":54,"line":121},4,[52,123,124],{"class":72},"        .{ .",[52,126,127],{"class":62},"path",[52,129,66],{"class":58},[52,131,132],{"class":98}," \"\u002Fbase.pkl\"",[52,134,135],{"class":72},", .",[52,137,138],{"class":62},"contents",[52,140,66],{"class":58},[52,142,144],{"class":143},"sj4cs"," @embedFile",[52,146,147],{"class":72},"(",[52,149,150],{"class":98},"\"pkl\u002Fbase.pkl\"",[52,152,153],{"class":72},") },\n",[52,155,157,159,161,163,166,168,170,172,174,176,179],{"class":54,"line":156},5,[52,158,124],{"class":72},[52,160,127],{"class":62},[52,162,66],{"class":58},[52,164,165],{"class":98}," \"\u002Fservices\u002Fapi.pkl\"",[52,167,135],{"class":72},[52,169,138],{"class":62},[52,171,66],{"class":58},[52,173,144],{"class":143},[52,175,147],{"class":72},[52,177,178],{"class":98},"\"pkl\u002Fservices\u002Fapi.pkl\"",[52,180,153],{"class":72},[52,182,184],{"class":54,"line":183},6,[52,185,186],{"class":72},"    },\n",[52,188,190],{"class":54,"line":189},7,[52,191,192],{"class":72},"};\n",[15,194,195,196,199,200,203],{},"Entries are addressed as ",[19,197,198],{},"embedded:\u002Fbase.pkl",". Relative imports and globbing (",[19,201,202],{},"import*(\"embedded:\u002Fservices\u002F*.pkl\")",") work because the reader is hierarchical and globbable by default.",[15,205,206,209,210,213,214,217,218,221],{},[19,207,208],{},"reader.Filesystem"," serves one directory tree through an open ",[19,211,212],{},"std.Io.Dir"," handle. It refuses paths that leave the tree, including through ",[19,215,216],{},".."," and symlinks. Open the directory with ",[19,219,220],{},".iterate = true"," when modules glob it.",[28,223,225],{"id":224},"register-readers","Register readers",[43,227,229],{"className":45,"code":228,"language":47,"meta":48,"style":48},"const module_readers = [_]zig_pkl.ModuleReader{embedded.moduleReader()};\nconst resource_readers = [_]zig_pkl.ResourceReader{secrets.resourceReader()};\n\nvar builder = try zig_pkl.Builder.restricted(allocator);\ndefer builder.deinit();\n_ = try builder.moduleReaders(&module_readers);\n_ = try builder.resourceReaders(&resource_readers);\nconst evaluator = try manager.createEvaluator(builder.options, &rejected);\n",[19,230,231,273,307,313,345,360,385,409],{"__ignoreMap":48},[52,232,233,236,239,241,244,247,250,253,255,258,261,264,266,270],{"class":54,"line":55},[52,234,235],{"class":58},"const",[52,237,238],{"class":62}," module_readers",[52,240,66],{"class":58},[52,242,243],{"class":72}," [",[52,245,246],{"class":62},"_",[52,248,249],{"class":72},"]",[52,251,252],{"class":62},"zig_pkl",[52,254,73],{"class":72},[52,256,257],{"class":62},"ModuleReader",[52,259,260],{"class":72},"{",[52,262,263],{"class":62},"embedded",[52,265,73],{"class":72},[52,267,269],{"class":268},"sScJk","moduleReader",[52,271,272],{"class":72},"()};\n",[52,274,275,277,280,282,284,286,288,290,292,295,297,300,302,305],{"class":54,"line":87},[52,276,235],{"class":58},[52,278,279],{"class":62}," resource_readers",[52,281,66],{"class":58},[52,283,243],{"class":72},[52,285,246],{"class":62},[52,287,249],{"class":72},[52,289,252],{"class":62},[52,291,73],{"class":72},[52,293,294],{"class":62},"ResourceReader",[52,296,260],{"class":72},[52,298,299],{"class":62},"secrets",[52,301,73],{"class":72},[52,303,304],{"class":268},"resourceReader",[52,306,272],{"class":72},[52,308,309],{"class":54,"line":105},[52,310,312],{"emptyLinePlaceholder":311},true,"\n",[52,314,315,317,320,322,325,327,329,332,334,337,339,342],{"class":54,"line":121},[52,316,59],{"class":58},[52,318,319],{"class":62}," builder",[52,321,66],{"class":58},[52,323,324],{"class":58}," try",[52,326,69],{"class":62},[52,328,73],{"class":72},[52,330,331],{"class":62},"Builder",[52,333,73],{"class":72},[52,335,336],{"class":268},"restricted",[52,338,147],{"class":72},[52,340,341],{"class":62},"allocator",[52,343,344],{"class":72},");\n",[52,346,347,350,352,354,357],{"class":54,"line":156},[52,348,349],{"class":58},"defer",[52,351,319],{"class":62},[52,353,73],{"class":72},[52,355,356],{"class":268},"deinit",[52,358,359],{"class":72},"();\n",[52,361,362,364,366,368,370,372,375,377,380,383],{"class":54,"line":183},[52,363,246],{"class":62},[52,365,66],{"class":58},[52,367,324],{"class":58},[52,369,319],{"class":62},[52,371,73],{"class":72},[52,373,374],{"class":268},"moduleReaders",[52,376,147],{"class":72},[52,378,379],{"class":58},"&",[52,381,382],{"class":62},"module_readers",[52,384,344],{"class":72},[52,386,387,389,391,393,395,397,400,402,404,407],{"class":54,"line":189},[52,388,246],{"class":62},[52,390,66],{"class":58},[52,392,324],{"class":58},[52,394,319],{"class":62},[52,396,73],{"class":72},[52,398,399],{"class":268},"resourceReaders",[52,401,147],{"class":72},[52,403,379],{"class":58},[52,405,406],{"class":62},"resource_readers",[52,408,344],{"class":72},[52,410,412,414,417,419,421,424,426,429,431,434,436,439,442,444,447],{"class":54,"line":411},8,[52,413,235],{"class":58},[52,415,416],{"class":62}," evaluator",[52,418,66],{"class":58},[52,420,324],{"class":58},[52,422,423],{"class":62}," manager",[52,425,73],{"class":72},[52,427,428],{"class":268},"createEvaluator",[52,430,147],{"class":72},[52,432,433],{"class":62},"builder",[52,435,73],{"class":72},[52,437,438],{"class":62},"options",[52,440,441],{"class":72},", ",[52,443,379],{"class":58},[52,445,446],{"class":62},"rejected",[52,448,344],{"class":72},[15,450,451],{},"The builder adds each reader's scheme to the allow lists. Readers, their contexts, and the builder must stay alive until the evaluator is closed.",[28,453,455],{"id":454},"write-a-reader","Write a reader",[15,457,458],{},"A reader is a pointer plus a vtable:",[43,460,462],{"className":45,"code":461,"language":47,"meta":48,"style":48},"const Secrets = struct {\n    table: []const [2][]const u8,\n\n    fn resourceReader(self: *Secrets) zig_pkl.ResourceReader {\n        return .{ .ptr = self, .vtable = &.{\n            .scheme = scheme,\n            .has_hierarchical_uris = no,\n            .is_globbable = no,\n            .read = read,\n            .list = list,\n        } };\n    }\n\n    fn read(ptr: *anyopaque, allocator: std.mem.Allocator, uri: []const u8) anyerror![]u8 {\n        const self: *Secrets = @ptrCast(@alignCast(ptr));\n        for (self.table) |row| {\n            if (std.mem.eql(u8, row[0], uri[\"secret:\".len..])) return allocator.dupe(u8, row[1]);\n        }\n        return error.SecretNotFound;\n    }\n    \u002F\u002F scheme, no, and list omitted\n};\n",[19,463,464,479,504,508,541,568,583,597,610,625,640,646,652,657,716,747,775,853,859,875,880,887],{"__ignoreMap":48},[52,465,466,468,471,473,476],{"class":54,"line":55},[52,467,235],{"class":58},[52,469,470],{"class":62}," Secrets",[52,472,66],{"class":58},[52,474,475],{"class":58}," struct",[52,477,478],{"class":72}," {\n",[52,480,481,484,487,489,491,494,497,499,502],{"class":54,"line":87},[52,482,483],{"class":62},"    table",[52,485,486],{"class":72},": []",[52,488,235],{"class":58},[52,490,243],{"class":72},[52,492,493],{"class":143},"2",[52,495,496],{"class":72},"][]",[52,498,235],{"class":58},[52,500,501],{"class":58}," u8",[52,503,102],{"class":72},[52,505,506],{"class":54,"line":105},[52,507,312],{"emptyLinePlaceholder":311},[52,509,510,513,516,518,521,524,527,530,533,535,537,539],{"class":54,"line":121},[52,511,512],{"class":58},"    fn",[52,514,515],{"class":268}," resourceReader",[52,517,147],{"class":72},[52,519,520],{"class":62},"self",[52,522,523],{"class":72},": ",[52,525,526],{"class":58},"*",[52,528,529],{"class":62},"Secrets",[52,531,532],{"class":72},") ",[52,534,252],{"class":62},[52,536,73],{"class":72},[52,538,294],{"class":62},[52,540,478],{"class":72},[52,542,543,546,549,552,554,557,559,562,564,566],{"class":54,"line":156},[52,544,545],{"class":58},"        return",[52,547,548],{"class":72}," .{ .",[52,550,551],{"class":62},"ptr",[52,553,66],{"class":58},[52,555,556],{"class":62}," self",[52,558,135],{"class":72},[52,560,561],{"class":62},"vtable",[52,563,66],{"class":58},[52,565,115],{"class":58},[52,567,118],{"class":72},[52,569,570,573,576,578,581],{"class":54,"line":183},[52,571,572],{"class":72},"            .",[52,574,575],{"class":62},"scheme",[52,577,66],{"class":58},[52,579,580],{"class":62}," scheme",[52,582,102],{"class":72},[52,584,585,587,590,592,595],{"class":54,"line":189},[52,586,572],{"class":72},[52,588,589],{"class":62},"has_hierarchical_uris",[52,591,66],{"class":58},[52,593,594],{"class":62}," no",[52,596,102],{"class":72},[52,598,599,601,604,606,608],{"class":54,"line":411},[52,600,572],{"class":72},[52,602,603],{"class":62},"is_globbable",[52,605,66],{"class":58},[52,607,594],{"class":62},[52,609,102],{"class":72},[52,611,613,615,618,620,623],{"class":54,"line":612},9,[52,614,572],{"class":72},[52,616,617],{"class":62},"read",[52,619,66],{"class":58},[52,621,622],{"class":62}," read",[52,624,102],{"class":72},[52,626,628,630,633,635,638],{"class":54,"line":627},10,[52,629,572],{"class":72},[52,631,632],{"class":62},"list",[52,634,66],{"class":58},[52,636,637],{"class":62}," list",[52,639,102],{"class":72},[52,641,643],{"class":54,"line":642},11,[52,644,645],{"class":72},"        } };\n",[52,647,649],{"class":54,"line":648},12,[52,650,651],{"class":72},"    }\n",[52,653,655],{"class":54,"line":654},13,[52,656,312],{"emptyLinePlaceholder":311},[52,658,660,662,664,666,668,670,673,675,677,679,682,684,687,689,692,694,697,699,701,703,705,708,711,714],{"class":54,"line":659},14,[52,661,512],{"class":58},[52,663,622],{"class":268},[52,665,147],{"class":72},[52,667,551],{"class":62},[52,669,523],{"class":72},[52,671,672],{"class":58},"*anyopaque",[52,674,441],{"class":72},[52,676,341],{"class":62},[52,678,523],{"class":72},[52,680,681],{"class":62},"std",[52,683,73],{"class":72},[52,685,686],{"class":62},"mem",[52,688,73],{"class":72},[52,690,691],{"class":62},"Allocator",[52,693,441],{"class":72},[52,695,696],{"class":62},"uri",[52,698,486],{"class":72},[52,700,235],{"class":58},[52,702,501],{"class":58},[52,704,532],{"class":72},[52,706,707],{"class":58},"anyerror!",[52,709,710],{"class":72},"[]",[52,712,713],{"class":58},"u8",[52,715,478],{"class":72},[52,717,719,722,724,726,728,730,732,735,737,740,742,744],{"class":54,"line":718},15,[52,720,721],{"class":58},"        const",[52,723,556],{"class":62},[52,725,523],{"class":72},[52,727,526],{"class":58},[52,729,529],{"class":62},[52,731,66],{"class":58},[52,733,734],{"class":143}," @ptrCast",[52,736,147],{"class":72},[52,738,739],{"class":143},"@alignCast",[52,741,147],{"class":72},[52,743,551],{"class":62},[52,745,746],{"class":72},"));\n",[52,748,750,753,756,758,760,763,765,768,771,773],{"class":54,"line":749},16,[52,751,752],{"class":58},"        for",[52,754,755],{"class":72}," (",[52,757,520],{"class":62},[52,759,73],{"class":72},[52,761,762],{"class":62},"table",[52,764,532],{"class":72},[52,766,767],{"class":58},"|",[52,769,770],{"class":62},"row",[52,772,767],{"class":58},[52,774,478],{"class":72},[52,776,778,781,783,785,787,789,791,794,796,798,800,802,805,808,811,813,815,818,820,823,826,829,832,834,837,839,841,843,845,847,850],{"class":54,"line":777},17,[52,779,780],{"class":58},"            if",[52,782,755],{"class":72},[52,784,681],{"class":62},[52,786,73],{"class":72},[52,788,686],{"class":62},[52,790,73],{"class":72},[52,792,793],{"class":268},"eql",[52,795,147],{"class":72},[52,797,713],{"class":58},[52,799,441],{"class":72},[52,801,770],{"class":62},[52,803,804],{"class":72},"[",[52,806,807],{"class":143},"0",[52,809,810],{"class":72},"], ",[52,812,696],{"class":62},[52,814,804],{"class":72},[52,816,817],{"class":98},"\"secret:\"",[52,819,73],{"class":72},[52,821,822],{"class":62},"len",[52,824,825],{"class":72},"..])) ",[52,827,828],{"class":58},"return",[52,830,831],{"class":62}," allocator",[52,833,73],{"class":72},[52,835,836],{"class":268},"dupe",[52,838,147],{"class":72},[52,840,713],{"class":58},[52,842,441],{"class":72},[52,844,770],{"class":62},[52,846,804],{"class":72},[52,848,849],{"class":143},"1",[52,851,852],{"class":72},"]);\n",[52,854,856],{"class":54,"line":855},18,[52,857,858],{"class":72},"        }\n",[52,860,862,864,867,869,872],{"class":54,"line":861},19,[52,863,545],{"class":58},[52,865,866],{"class":58}," error",[52,868,73],{"class":72},[52,870,871],{"class":62},"SecretNotFound",[52,873,874],{"class":72},";\n",[52,876,878],{"class":54,"line":877},20,[52,879,651],{"class":72},[52,881,883],{"class":54,"line":882},21,[52,884,886],{"class":885},"sJ8bj","    \u002F\u002F scheme, no, and list omitted\n",[52,888,890],{"class":54,"line":889},22,[52,891,192],{"class":72},[893,894,895,904,907,915],"ul",{},[896,897,898,900,901,903],"li",{},[19,899,617],{}," returns bytes allocated with the ",[19,902,341],{}," it receives. The manager frees them after replying.",[896,905,906],{},"An error is sent to Pkl as the error's name, and the evaluation fails with that message.",[896,908,909,911,912,914],{},[19,910,632],{}," returns the children of a URI for globbing, also allocated with ",[19,913,341],{},". Readers that are not globbable may return an empty slice.",[896,916,917,918,921],{},"Module readers also report ",[19,919,920],{},"is_local",": whether their modules count as local for Pkl's import rules.",[15,923,924,925,73],{},"The complete program is ",[926,927,929],"a",{"href":928},"..\u002F..\u002Fexamples\u002Freaders\u002Fmain.zig",[19,930,931],{},"examples\u002Freaders",[28,933,935],{"id":934},"threads","Threads",[15,937,938,939,942,943,946],{},"Reader callbacks run on a pool of worker threads, so a slow reader does not hold up other responses. ",[19,940,941],{},"InitOptions.reader_workers"," (default 4) caps the pool, and workers start only when callbacks arrive. When ",[19,944,945],{},"InitOptions.reader_queue_capacity"," (default 64) callbacks are already waiting, Pkl receives an error for the next one instead of the queue growing without bound.",[15,948,949,950,953],{},"One reader instance may serve several evaluators at once, so make its state thread-safe. ",[19,951,952],{},"Evaluator.close"," waits for that evaluator's running callbacks before it returns.",[955,956,957],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}",{"title":48,"searchDepth":87,"depth":87,"links":959},[960,961,962,963],{"id":30,"depth":87,"text":31},{"id":224,"depth":87,"text":225},{"id":454,"depth":87,"text":455},{"id":934,"depth":87,"text":935},"A reader serves modules or resources for a URI scheme from your program. Pkl asks the reader whenever a module imports scheme:... or calls read(\"scheme:...\"), and the answer never touches the disk unless the reader reads it.","md",{},"\u002Fguides\u002Freaders",{"title":6,"description":964},"guides\u002Freaders","H9JxuKzv7PW4X5yXnj05vLYLtW0uj78A4HCrIVaSck4","docs\u002Fguides\u002Freaders.md",[973,977,981,985,989,993,997,1001,1005,1009,1013,1017,1018],{"title":974,"path":975,"stem":976},"Version compatibility","\u002Fguides\u002Fcompatibility","guides\u002Fcompatibility",{"title":978,"path":979,"stem":980},"Concurrency","\u002Fguides\u002Fconcurrency","guides\u002Fconcurrency",{"title":982,"path":983,"stem":984},"Errors","\u002Fguides\u002Ferrors","guides\u002Ferrors",{"title":986,"path":987,"stem":988},"Evaluation","\u002Fguides\u002Fevaluation","guides\u002Fevaluation",{"title":990,"path":991,"stem":992},"External readers","\u002Fguides\u002Fexternal-readers","guides\u002Fexternal-readers",{"title":994,"path":995,"stem":996},"Installation","\u002Fguides\u002Finstallation","guides\u002Finstallation",{"title":998,"path":999,"stem":1000},"Logging","\u002Fguides\u002Flogging","guides\u002Flogging",{"title":1002,"path":1003,"stem":1004},"Migrating from pkl-zig","\u002Fguides\u002Fmigration","guides\u002Fmigration",{"title":1006,"path":1007,"stem":1008},"Ownership","\u002Fguides\u002Fownership","guides\u002Fownership",{"title":1010,"path":1011,"stem":1012},"Projects","\u002Fguides\u002Fprojects","guides\u002Fprojects",{"title":1014,"path":1015,"stem":1016},"Quick start","\u002Fguides\u002Fquickstart","guides\u002Fquickstart",{"title":6,"path":967,"stem":969},{"title":1019,"path":1020,"stem":1021},"Security","\u002Fguides\u002Fsecurity","guides\u002Fsecurity",1792908673089]